Как ускорить клонирование массива в С#?

Я работаю над решением проблемы Cult of the Bound Variable.

В части проблемы вы внедряете интерпретатор для "древней" универсальной машины. Я внедрил intrereter для машины, которую они описывают, и теперь я запускаю тестовую программу, которую университет предоставил для ее тестирования.

My С# реализация этого интерпретатора медленно!

Я активировал свою программу в профилировщике ANTS, чтобы увидеть, где происходит замедление, и я вижу, что более 96% моего времени занято операцией "Загрузить программу".

ANTS Profile Results

спецификация этого оператора выглядит следующим образом:

 #12. Load Program.

              The array identified by the B register is duplicated
              and the duplicate shall replace the '0' array,
              regardless of size. The execution finger is placed
              to indicate the platter of this array that is
              described by the offset given in C, where the value
              0 denotes the first platter, 1 the second, et
              cetera.

              The '0' array shall be the most sublime choice for
              loading, and shall be handled with the utmost
              velocity.

Вот мой код для этого оператора:

case 12: // Load Program
    _platters[0] = (UInt32[])_platters[(int)_registers[B]].Clone();
    _finger = _registers[C];
    break;

Исходный код для всего моего интерпретатора "Универсальная машина" здесь.

Что я могу сделать, чтобы сделать это быстрее? Существуют и другие реализации этого интерпретатора, написанного на языке C, которые значительно ускоряют весь эталон.

Ответ 1

Вы можете попробовать Buffer.BlockCopy, хотя я был бы удивлен, если бы в этом случае имело место огромное различие:

case 12: // Load Program
    uint[] src = _platters[(int)_registers[B]];
    _platters[0] = new uint[src.Length];
    Buffer.BlockCopy(src, 0, _platters[0], 0, src.Length * 4);
    _finger = _registers[C];
    break;

Ответ 4

В зависимости от того, как используются два результирующих массива, вы можете использовать модификацию copy-on-write:

Вы не будете использовать массивы напрямую, но с помощью обертки. Чтобы клонировать массив, просто создайте другую оболочку. Если вы попытаетесь написать массив, который используется более чем одной оберткой, вы делаете фактическое клонирование и отделяете обертки.

Ответ 5

Помимо обсуждаемого вопроса, истинная причина, по которой ваши тесты в области производительности настолько низки, что вы должны обрабатывать 0 "с максимальной скоростью", как говорит спецификация;)

По существу, регулярные прыжки выполняются путем нагрузки от 0 до 0. Это очень часто встречается в коде кода. Вы должны полностью избегать клонирования и обновлять только "палец" в этом конкретном случае.