Я имею дело с проблемой, которая должна работать с большим количеством данных. В настоящее время его значения представлены как unsigned int
. Я знаю, что действительные значения не превышают предел 1000
.
Я могу использовать unsigned short
сохранить его. Позитивный аспект к этому - то, что это будет использовать меньше пространства памяти для хранения значения. Производительность пострадает?
Если я решил хранить данные как short
но весь вызов функционирует использование int
, это распознано, что я должен преобразовать между этими типами данных при хранении или извлечении значений. Производительность пострадает? Будет потеря в производительности быть поразительной?
Если я решил не использовать short
но всего 10 битов, упакованных в массив unsigned int
. Что произойдет в этом случае, соответствующем предыдущим?
Это все зависит от архитектуры. Битовые поля как правило медленнее, но если вы сможете значительно сократить использование памяти с ними, вы можете даже выиграть в производительности за счет лучшего кэширования процессора и подобных вещей. Аналогично и с короткими (хотя в любом случае это не драматично).
Лучший способ - сделать ваш исходный код способным легко переключать представление (во время компиляции, конечно). Тогда вы сможете тестировать и профилировать различные реализации в ваших конкретных обстоятельствах, просто изменив, скажем, одно #define
.
Кроме того, не забывайте о правиле преждевременной оптимизации. Сначала сделайте так, чтобы это работало. Если окажется, что это медленно/не достаточно быстро, только потом пытайтесь ускорить.
Я могу использовать беззнаковое сокращение, чтобы сохранить его.
Да, вы можете использовать unsigned short (при условии (sizeof (unsigned short) * CHAR_BITS)> = 10)
Положительным моментом является то, что для хранения значения будет использоваться меньше места в памяти.
Меньше чем что? Меньше, чем int? Зависит от размера sizeof (int) в вашей системе?
Пострадает ли производительность?
Зависит. Предполагается, что тип int является наиболее эффективным целочисленным типом для вашей системы, поэтому потенциально использование short может повлиять на вашу производительность. Будет ли это зависеть от системы. Найдите время и узнайте.
Если я решил хранить данные как можно более короткими, но все вызывающие функции используют int, я понял, что мне нужно преобразовывать между этими типами данных при сохранении или извлечении значений.
Да. Но компилятор выполнит преобразование автоматически. Одна вещь, на которую вам нужно обратить внимание, - это преобразование между знаковыми и беззнаковыми типами. Если значение не соответствует точному результату, это может быть определено реализацией.
Пострадает ли производительность?
Может быть. если sizeof (unsigned int) == sizeof (unsigned short), то, вероятно, нет. Время и увидишь.
Будет ли потеря производительности драматичной?
Время и посмотрим.
Если бы я решил не использовать short, а просто упаковал 10 бит в массив беззнаковых int. Что будет в этом случае по сравнению с предыдущими?
Заметьте и посмотрите.
Хорошим компромиссом для вас, вероятно, будет упаковка трех значений в 32-битный int (с двумя неиспользуемыми битами). Распутывание 10 битов из битового массива обходится гораздо дороже и не экономит много места. Вы можете либо использовать битовые поля, либо сделать это вручную:
(i&0x3FF) // Get i[0]
(i>>10)&0x3FF // Get i[1]
(i>>20)&0x3FF // Get i[2]
i = (i&0x3FFFFC00) | (j&0x3FF) // Set i[0] to j
i = (i&0x3FF003FF) | ((j&0x3FF)<<10) // Set i[1] to j
i = (i&0xFFFFF) | ((j&0x3FF)<<20) // Set i[2] to j
Здесь видно, сколько это дополнительных затрат: битовая операция и 2/3 сдвига (в среднем) для get, и три битовых операции и 2/3 сдвига (в среднем) для set. Наверное, это не так уж плохо, особенно если вы в основном получаете значения, а не устанавливаете их.