Почему это улучшает производительность?

Попробуйте это:

twoDec = Math.Round(val, 2)
8
задан Kasper Holdum 22 October 2009 в 22:46
поделиться

6 ответов

Это вопрос организации данных. Думайте о памяти как об одномерном массиве. Вот как на самом деле все устроено на диске (с точки зрения компьютера). Итак, при создании многомерных массивов, когда вы меняете порядок циклов, вы меняете способ обхода массива. Вместо того чтобы читать по порядку, вы прыгаете с позиции на позицию.


Многомерный массив для вас выглядит так:

3x3 matrix

И так для компьютера. Оптимальный способ перемещения имеет индексы, следующие за стрелкой ниже: Linear traversed array

Итак, когда вы меняете цикл массива, массив проходит следующим образом: Array traversed by switched array loops

Таким образом, вы получаете больше промахов в кэш-памяти и менее эффективный алгоритм.

19
ответ дан 5 December 2019 в 06:38
поделиться

Местность, местонахождение, местонахождение данных. Из Википедии (где написано лучше, чем у меня):

Линейные структуры данных: Локальность часто возникает из-за того, что код содержит циклы, которые имеют тенденцию ссылаться на массивы или другие структуры данных по индексам. Последовательная локальность, особый случай пространственной локальности, возникает, когда соответствующие элементы данных упорядочены и доступны линейно. Например, простой обход элементов в одномерном массиве от базового адреса к самому высокому элементу будет использовать последовательную локализацию массива в памяти. [2] Более общая эквидистантная локальность возникает, когда линейный обход проходит по более длинной области смежных структур данных, имеющих идентичную структуру и размер, и в дополнение к этому, не все структуры доступны, но только взаимно соответствующие одинаковые элементы конструкций. Это тот случай, когда матрица представлена ​​как последовательная матрица строк и требуется доступ к одному столбцу матрицы.

4
ответ дан 5 December 2019 в 06:38
поделиться

Я бы также подумал, что относительные размеры массивов a и b будут иметь значение.

Если a.length большое, а b.length мало, второй вариант должен быть быстрее . И наоборот, если a.length мала, а b.length - большая, первый вариант будет быстрее. Проблема заключается в том, чтобы избежать затрат на установку / разборку внутреннего цикла.

Кстати, почему у вас

int aLen = a.Length;

Но тогда также вызывается a.Length напрямую? Похоже, вам следует выбрать то или иное.

0
ответ дан 5 December 2019 в 06:38
поделиться

Скорее всего, это связано с попаданиями / промахами в кеш. Разница заключается в последовательном и разрозненном доступе, размер которого превышает размер одной строки кэша.

Для простых циклов C ++ также может помочь сделать циклы в обратном направлении, чтобы немного повысить производительность цикла. Не знаю, подходит ли он для .NET.

1
ответ дан 5 December 2019 в 06:38
поделиться

Ваша интуиция верна, это проблема кеширования. Сообщение @Mike Daniels на вопрос ниже по сути описывает ту же проблему. Второй фрагмент кода получит гораздо больше попаданий в кеш.

Самый быстрый способ перебрать 2-мерный массив?

Но, тсс, мы не должны заботиться о производительности, верно? :)

1
ответ дан 5 December 2019 в 06:38
поделиться

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

0
ответ дан 5 December 2019 в 06:38
поделиться
Другие вопросы по тегам:

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