De / массив Чередования быстро в C#

В качестве альтернативы используйте фильтр.

Создайте пустую страницу в своем блоге WordPress, названную так, как вам нужно. Обратите внимание на post_id. Затем создайте фильтр, который изменяет его постоянную ссылку.

add_filter('get_the_permalink','my_permalink_redirect');
function my_permalink_redirect($permalink) {
    global $post;
    if ($post->ID == your_post_id_here) {
        $permalink = 'http://new-url.com/pagename';
    }
    return $permalink;
}

Таким образом, URL будет корректно отображаться на странице, никаких смешных перенаправлений не требуется.

Если вам нужно сделать это много, подумайте об использовании настраиваемых полей postmeta для определения значения postmeta для «offsite_url» или чего-то подобного, затем вы можете создавать страницы по мере необходимости, вводить значение «offsite_url» и затем используйте фильтр, подобный приведенному выше, вместо того, чтобы проверять post_id, который вы проверяете, чтобы увидеть, имеет ли он требуемый postmeta, и при необходимости изменять постоянную ссылку.

6
задан MaXKilleR 7 June 2009 в 12:00
поделиться

5 ответов

Я провел несколько тестов и вот код, который я тестировал:

delegate(float[] inout)
{ // My Original Code
    float[][] tempbuf = new float[2][];
    int length = inout.Length / 2;
    for (int c = 0; c < 2; c++)
    {
        tempbuf[c] = new float[length];
        for (int i = 0, offset = c; i < tempbuf[c].Length; i++, offset += 2)
            tempbuf[c][i] = inout[offset];
    }
}
delegate(float[] inout)
{ // jerryjvl's recommendation: loop unrolling
    float[][] tempbuf = new float[2][];
    int length = inout.Length / 2;
    for (int c = 0; c < 2; c++)
        tempbuf[c] = new float[length];
    for (int ix = 0, i = 0; ix < length; ix++)
    {
        tempbuf[0][ix] = inout[i++];
        tempbuf[1][ix] = inout[i++];
    }

}
delegate(float[] inout)
{ // Unsafe Code
    unsafe
    {
        float[][] tempbuf = new float[2][];
        int length = inout.Length / 2;
        fixed (float* buffer = inout)
            for (int c = 0; c < 2; c++)
            {
                tempbuf[c] = new float[length];
                float* offset = buffer + c;
                fixed (float* buffer2 = tempbuf[c])
                {
                    float* p = buffer2;
                    for (int i = 0; i < length; i++, offset += 2)
                        *p++ = *offset;
                }
            }
    }
}
delegate(float[] inout)
{ // Modifying my original code to see if the compiler is not as smart as i think it is.
    float[][] tempbuf = new float[2][];
    int length = inout.Length / 2;
    for (int c = 0; c < 2; c++)
    {
        float[] buf = tempbuf[c] = new float[length];
        for (int i = 0, offset = c; i < buf.Length; i++, offset += 2)
            buf[i] = inout[offset];
    }
}

и результаты: (размер буфера = 2 ^ 17, количество итераций, рассчитанных на тест = 200)

Average for test #1:      0.001286 seconds +/- 0.000026
Average for test #2:      0.001193 seconds +/- 0.000025
Average for test #3:      0.000686 seconds +/- 0.000009
Average for test #4:      0.000847 seconds +/- 0.000008

Average for test #1:      0.001210 seconds +/- 0.000012
Average for test #2:      0.001048 seconds +/- 0.000012
Average for test #3:      0.000690 seconds +/- 0.000009
Average for test #4:      0.000883 seconds +/- 0.000011

Average for test #1:      0.001209 seconds +/- 0.000015
Average for test #2:      0.001060 seconds +/- 0.000013
Average for test #3:      0.000695 seconds +/- 0.000010
Average for test #4:      0.000861 seconds +/- 0.000009

Я получил аналогичный результаты каждого теста. Очевидно, что небезопасный код является самым быстрым, но я был удивлен, увидев, что CLS не может понять, что он может отбросить проверки индекса при работе с неровным массивом. Может быть, кто-нибудь придумает другие способы оптимизации моих тестов.

Изменить: Я попробовал развернуть цикл с небезопасным кодом, но это не дало результата. Я также попытался оптимизировать метод разворачивания цикла:

delegate(float[] inout)
{
    float[][] tempbuf = new float[2][];
    int length = inout.Length / 2;
    float[] tempbuf0 = tempbuf[0] = new float[length];
    float[] tempbuf1 = tempbuf[1] = new float[length];

    for (int ix = 0, i = 0; ix < length; ix++)
    {
        tempbuf0[ix] = inout[i++];
        tempbuf1[ix] = inout[i++];
    }
}

Результаты также оказались неудачными по сравнению с тестом №4 с разницей в 1%. Пока что лучше всего мне подходит тест №4.

Как я сказал jerryjvl, проблема заключается в том, чтобы CLS не индексировал входной буфер, поскольку добавление второй проверки (&& offset

Редактировать 2: Раньше я запускал тесты в среде IDE, поэтому вот результаты снаружи:

2^17 items, repeated 200 times
******************************************
Average for test #1:      0.000533 seconds +/- 0.000017
Average for test #2:      0.000527 seconds +/- 0.000016
Average for test #3:      0.000407 seconds +/- 0.000008
Average for test #4:      0.000374 seconds +/- 0.000008
Average for test #5:      0.000424 seconds +/- 0.000009

2^17 items, repeated 200 times
******************************************
Average for test #1:      0.000547 seconds +/- 0.000016
Average for test #2:      0.000732 seconds +/- 0.000020
Average for test #3:      0.000423 seconds +/- 0.000009
Average for test #4:      0.000360 seconds +/- 0.000008
Average for test #5:      0.000406 seconds +/- 0.000008


2^18 items, repeated 200 times
******************************************
Average for test #1:      0.001295 seconds +/- 0.000036
Average for test #2:      0.001283 seconds +/- 0.000020
Average for test #3:      0.001085 seconds +/- 0.000027
Average for test #4:      0.001035 seconds +/- 0.000025
Average for test #5:      0.001130 seconds +/- 0.000025

2^18 items, repeated 200 times
******************************************
Average for test #1:      0.001234 seconds +/- 0.000026
Average for test #2:      0.001319 seconds +/- 0.000023
Average for test #3:      0.001309 seconds +/- 0.000025
Average for test #4:      0.001191 seconds +/- 0.000026
Average for test #5:      0.001196 seconds +/- 0.000022

Test#1 = My Original Code
Test#2 = Optimized safe loop unrolling
Test#3 = Unsafe code - loop unrolling
Test#4 = Unsafe code
Test#5 = My Optimized Code

Похоже, разворачивание цикла неблагоприятно. Мой оптимизированный код по-прежнему остается моим лучшим вариантом, и разница лишь в 10% по сравнению с небезопасным кодом. Если бы я только мог сказать компилятору, что (i

5
ответ дан 16 December 2019 в 21:45
поделиться

Поскольку для этого нет встроенной функции, использование индексов массива - самая быстрая операция, о которой вы могли подумать. Индексаторы и подобные решения только усугубляют ситуацию, вводя вызовы методов и не позволяя JIT-оптимизатору оптимизировать связанные проверки.

В любом случае, я думаю, что ваш текущий метод является самым быстрым не небезопасным решением, которое вы можете можно было бы использовать. Если производительность действительно важна для вас (что обычно имеет значение в приложениях для обработки сигналов), вы можете сделать все это в unsafe C # (что достаточно быстро, вероятно, сравнимо с C) и обернуть это в метод, который вы буду звонить из ваших безопасных методов.

1
ответ дан 16 December 2019 в 21:45
поделиться

Это не даст вам серьезного повышение производительности (я примерно измерил 20% на моей машине), но вы можете рассмотреть возможность развертывания цикла для общих случаев. Если в большинстве случаев у вас относительно ограниченное количество каналов:

static private float[][] Alternative(float[] buffer, int channels)
{
    float[][] result = new float[channels][];
    int length = buffer.Length / channels;
    for (int c = 0; c < channels; c++)
        result[c] = new float[length];

    int i = 0;
    if (channels == 8)
    {
        for (int ix = 0; ix < length; ix++)
        {
            result[0][ix] = buffer[i++];
            result[1][ix] = buffer[i++];
            result[2][ix] = buffer[i++];
            result[3][ix] = buffer[i++];
            result[4][ix] = buffer[i++];
            result[5][ix] = buffer[i++];
            result[6][ix] = buffer[i++];
            result[7][ix] = buffer[i++];
        }
    }
    else
        for (int ix = 0; ix < length; ix++)
            for (int ch = 0; ch < channels; ch++)
                result[ch][ix] = buffer[i++];


    return result;
}

Пока вы оставите здесь общий резервный вариант, он будет обрабатывать любое количество каналов, но вы получите прирост скорости, если он будет одним из развернутые варианты.

1
ответ дан 16 December 2019 в 21:45
поделиться

Может быть, немного развернемся в вашем собственном лучшем ответе:

delegate(float[] inout)
{
    unsafe
    {
        float[][] tempbuf = new float[2][];
        int length = inout.Length / 2;

        fixed (float* buffer = inout)
        {
            float* pbuffer = buffer;

            tempbuf[0] = new float[length];
            tempbuf[1] = new float[length];

            fixed (float* buffer0 = tempbuf[0])
            fixed (float* buffer1 = tempbuf[1])
            {
                float* pbuffer0 = buffer0;
                float* pbuffer1 = buffer1;

                for (int i = 0; i < length; i++)
                {
                    *pbuffer0++ = *pbuffer++;
                    *pbuffer1++ = *pbuffer++;
                }
            }
        }
    }
}

Это может еще немного повысить производительность.

1
ответ дан 16 December 2019 в 21:45
поделиться

Думаю, многие читатели зададутся вопросом, почему вам не нужно небезопасное решение для чего-то вроде обработки звука. Это тот тип вещей, который требует горячей оптимизации, и я бы лично был недоволен, зная, что это принудительно осуществляется через виртуальную машину.

0
ответ дан 16 December 2019 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: