время доступа для маленького массива против маленькой структуры в c # - PullRequest
3 голосов
/ 20 августа 2009

Мне нужно обработать около 500 000 точек данных, каждая из которых состоит из 4 десятичных знаков. Я хотел бы использовать и массив структур для этого. Будет ли это намного медленнее, чем использование массива массивов? Кажется, что память не будет проблемой, но скорость будет - она ​​должна быть быстрой.

Быстрый пример кода из двух вариантов:

Вариант 1:

public struct Struct
{
    public decimal A { get; set; }
    public decimal B { get; set; }
    public decimal C { get; set; }
    public decimal D { get; set; }
}

Использование:

private Struct[] data;

Вариант 2:

private decimal [][] data;

Кроме того, decimal правильный тип данных для использования? Точки данных - деньги ...

Спасибо! Brian

Ответы [ 6 ]

4 голосов
/ 20 августа 2009

Если вы обрабатываете A, B, C, D в одно и то же время, метод массива структур должен иметь лучшую пространственную локализацию - поскольку данные сгруппированы вместе, они будут выгружаться в память и в одно и то же время неисправности) и загружаются в кэш процессора одновременно. Если вы обрабатываете все A, затем все B и т. Д., Обратное будет истинным, и вы должны использовать массив массивов.

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

2 голосов
/ 20 августа 2009

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

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

Конечно, разница проявляется только после миллионов просмотров.

1 голос
/ 20 августа 2009

Массив Struct и зубчатые массивы размещаются в памяти практически одинаково, поэтому при использовании их не должно быть снижения производительности.

public struct Struct
{
    // Unless you're filling your get/set blocks with anything,
    // these properties will be in-lined in compilation time
    // and will have the same performance/behavior as using public fields

    public decimal A { get; set; }
    public decimal B { get; set; }
    public decimal C { get; set; }
    public decimal D { get; set; }
}

Так что я бы подумал об использовании открытых полей. Но это только мое мнение, мне нравится четко знать, как все будет вести себя.

Об использовании десятичной дроби для денег, это не всегда так. десятичное - это 128-битное поле данных, оно имеет ОЧЕНЬ высокую точность, но его целочисленная часть имеет узкий диапазон значений. Если вам нужна высокая точность для расчета ставок или что-то в этом роде, но вам не нужны действительно высокие значения, выберите десятичную. Если вам нужны более высокие значения и не такая большая точность, выберите удвоение. Если вы имеете дело с небольшими значениями и просто нуждаетесь в достаточной точности, используйте float.

Помните, что чем ближе тип данных к 32-битному (или ширине шины), тем меньше времени потребуется для загрузки данных.

Надеюсь, это поможет!

1 голос
/ 20 августа 2009

При работе с деньгами часто быстрее и гораздо эффективнее использовать целые числа, если вы выполняете сравнение или простое сложение и вычитание, и вам не нужно беспокоиться об ошибках округления.

1 голос
/ 20 августа 2009

хмм ... Если вы замените массив массивов двумерным массивом, результирующий макет памяти должен быть более или менее эквивалентным:

private Struct[] data = new Struct[x];
private decimal[,] data = new decimal[x,4];

Если вы не надеялись передать один из массивов другим методам ...

1 голос
/ 20 августа 2009
  1. Десятичный тип - это правильный тип для использования, если вы работаете с валютными значениями.
  2. Массив структур будет довольно быстрым.

Имейте в виду, однако, что когда вы имеете дело с массивом структур, отдельные элементы структуры (особенно если у вас есть каждое значение как свойство) должны рассматриваться как один неизменный объект. Это означает, что если вы хотите изменить C в элементе массива 4, вам нужно сделать:

MyStruct val = array[5];
val.C = newValue;
array[5] = val;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...