В качестве альтернативы используйте фильтр.
Создайте пустую страницу в своем блоге 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, и при необходимости изменять постоянную ссылку.
Я провел несколько тестов и вот код, который я тестировал:
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, поэтому вот результаты снаружи: Похоже, разворачивание цикла неблагоприятно. Мой оптимизированный код по-прежнему остается моим лучшим вариантом, и разница лишь в 10% по сравнению с небезопасным кодом. Если бы я только мог сказать компилятору, что (i 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
Поскольку для этого нет встроенной функции, использование индексов массива - самая быстрая операция, о которой вы могли подумать. Индексаторы и подобные решения только усугубляют ситуацию, вводя вызовы методов и не позволяя JIT-оптимизатору оптимизировать связанные проверки.
В любом случае, я думаю, что ваш текущий метод является самым быстрым не небезопасным
решением, которое вы можете можно было бы использовать. Если производительность действительно важна для вас (что обычно имеет значение в приложениях для обработки сигналов), вы можете сделать все это в unsafe
C # (что достаточно быстро, вероятно, сравнимо с C) и обернуть это в метод, который вы буду звонить из ваших безопасных методов.
Это не даст вам серьезного повышение производительности (я примерно измерил 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;
}
Пока вы оставите здесь общий резервный вариант, он будет обрабатывать любое количество каналов, но вы получите прирост скорости, если он будет одним из развернутые варианты.
Может быть, немного развернемся в вашем собственном лучшем ответе:
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++;
}
}
}
}
}
Это может еще немного повысить производительность.
Думаю, многие читатели зададутся вопросом, почему вам не нужно небезопасное решение для чего-то вроде обработки звука. Это тот тип вещей, который требует горячей оптимизации, и я бы лично был недоволен, зная, что это принудительно осуществляется через виртуальную машину.