хранение двух шорт в одном коротком - PullRequest
0 голосов
/ 03 декабря 2009

Недавно я написал некоторый код, который использует одно и то же беззнаковое сокращение для хранения двух значений, результата и идентификатора, например:

unsigned short data = new_id();
// result is either 0 or 1 so store it in the rightmost bit and move the id left
data = (data << 1) + get_result();
// ... later ...
// now we can print results like
printf("%u: %u\n", data & 1, data >> 1);

Было бы лучше просто использовать структуру для хранения обоих значений, или этот тип вещей является общим / приемлемым? Программа уже хранит столько памяти, что я подумал, что начну искать способы уменьшить объем используемой памяти.

Ответы [ 8 ]

13 голосов
/ 03 декабря 2009

Битовые поля (но только если вам действительно нужно ограниченное пространство - то есть встроенные системы)?

typedef struct id_result {
    unsigned int id : 15;
    unsigned int result : 1;
} id_result;

в противном случае, да, используйте структуру с более полными и значимыми определениями:

typedef uint16 IDTYPE; /* assuming uint16 exists elsewhere */

typedef struct id_result {
    IDTYPE id;
    bool result;
} id_result;
7 голосов
/ 03 декабря 2009

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

Мне напоминают о времени, когда M68000 имел 32-разрядные адресные регистры, но фактически использовались только 24-битные из них. Программисты делали все "оптимизации", чтобы хранить информацию в этих других 8 битах. У мальчика были красные лица, когда более поздние версии чипа, такие как M68030, использовали все 32 бита.

2 голосов
/ 03 декабря 2009

Для тех, кто советует не экономить память с помощью битовых полей: с годами компьютеры получают больше гигабайтов, L1 $ (быстрая память) остается всего несколько десятков килобайт. Для большинства современных приложений большая часть времени тратится на ожидание медленной памяти в L1 $.

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

2 голосов
/ 03 декабря 2009

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

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

2 голосов
/ 03 декабря 2009

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

1 голос
/ 03 декабря 2009

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

struct myStruct {
int data:8;
int result:8;
};

Достигает того же результата по уменьшению памяти при одновременном повышении общей поддерживаемости кода.

0 голосов
/ 03 декабря 2009

Использование структур / объектов не обязательно лучший или самый ясный подход.

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

if ( item > 0 )
   item += blah

Но если у вас есть структура, то каждый бит арифметики теперь нуждается в членском доступе

if ( item.valid() ) 
   item.setValue(item.getValue() + blah);
0 голосов
/ 03 декабря 2009

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

...