Мне нужно сдвинуть вправо и влево массив по N местам.
Элементы, которые появляются на стороне, где я перемещаюсь, должны вернуться на другую сторону.
Сдвиг вправо на 13:
[0,1,2,3,4,5,6,7,8,9] -> [7,8,9,0,1,2,3,4,5,6]
Сдвиг влево на 15:
[0,1,2,3,4,5,6,7,8,9] -> [5,6,7,8,9,0,1,2,3,4]
Эта операция будет выполняться миллионы раз и должна быть очень быстрой.
Моя текущая реализация следующая. Пожалуйста, посмотрите и предложите, если есть какая-то оптимизация.
if (shift > 0)
{
int offset = array.Length % shift;
if (offset > 0)
{
byte[] temp = new byte[offset];
if (!right)
{
Array.Copy(array, temp, offset);
Array.Copy(array, offset, array, 0, array.Length - offset);
Array.Copy(temp, 0, array, array.Length - offset, temp.Length);
}
else
{
Array.Copy(array, array.Length - offset, temp, 0, offset);
Array.Copy(array, 0, array, offset, array.Length - offset);
Array.Copy(temp, 0, array, 0, temp.Length);
}
}
}
Как подсказка о том, насколько он будет сдвинут (но я сомневаюсь, что это может привести к оптимизации):
- depends on the entropy of the array itself
- for aray that are full of same values it will get shifted roughtly 0
- more entropy means higher shift value
- direction of shift will be used generally more to the left
PS. Не удается получить разрешение безопасности на запуск небезопасного кода:/
PS2: результирующий массив должен быть передан как массив вперед в другую библиотеку для дальнейшей обработки, поэтому я не могу просто обернуть и переиндексировать.
PS3: Я бы предпочел работать с одним и тем же массивом, так как метод использует ref
, и это делается в новом массиве, а затем копирование будет трудоемким (я использую массив temp для часть, которая выпадает из-за смещения).