Вопрос

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

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);

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

Это было полезно?

Решение

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

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;

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

if ( item > 0 )
   item += blah

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

if ( item.valid() ) 
   item.setValue(item.getValue() + blah);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top