30 августа 2006

Экономия на мелочах?

Некоротые товарищи пытаются сэкономить несколько байт, используя вместо int тип signed char или unsigned char. Их мотивация такая: если у нас числа не больше 127 (255), то зачем использовать четырехбайтный int (на 32 битной платформе), когда можно обойтись всего одним байтом? Экономия - 400%!

Но на деле есть а) выравнивание данных компилятором, б) размер процессорного слова.

Выравнивание может быть настроено на 4 или 8 байт и структура
struct { signed char x, y; } займет 8 или 16 байт, а не 2.

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

То есть никакой экономии памяти при переводе единичных переменных (не массивов) с int на char скорее всего не будет. Зато возможно будут некоторые проблемы.

Ситуация - чтение данных из текстового потока:
int value;
textstream >> value;


При входном потоке "0" мы получим value == 0. А при замене int на char получим value == 48. Сэкономили несколько байт, а получили лишнюю головную боль.

2 комментария:

sad комментирует...

Не нужно так категорично. =) В GCC 4.1.2 для struct A{signed char x, y;}; sizeof(A) все-таки показывает 2.
Вот если третье поле добавить типа int, вот тогда она будет уже 8 байт, а не 6 из-за выравнивания (на 32-х разрядной машине, ест-но).

Some gcc-specific trick =):
struct A{char x, y; int f}__attribute__((packed));

sizeof(A) выдаст 6. Но пользоваться такими вещами ИМХО изврат без очень сильной нужды.

В целом с заметкой полностью согласен.

ser комментирует...

Visual C++ Concepts: Porting and Upgrading
Structure Alignment

char: Align on byte boundaries
short (16-bit): Align on even byte boundaries
int and long (32-bit): Align on 32-bit boundaries
float: Align on 32-bit boundaries
double: Align on 64-bit boundaries
structures: Largest alignment requirement of any member
unions: Alignment requirement of the first member

Плюс практически в любом компиляторе есть #pragma pack.

Согласен с тем, что использовать char/short для экономии места нужды нет, на некоторых платформах могуть быть тормоза (например, на x86 при доступе к 16 bit из 32 бит кода).