Эффективное хранение данных - PullRequest
1 голос
/ 15 февраля 2010

может быть, у меня, как всегда, глупый вопрос, но почему-то я не могу понять, как хранить переменные, чтобы это было эффективно. Кстати, наш преподаватель по c ++ кое-что рассказал о том, как размер хранимого типа данных может повлиять на скорость его хранения (например, поиск ближайшего достаточного непрерывного блока памяти), и я хотел бы узнать больше об этом. Не могли бы вы дать мне несколько указаний?

Ответы [ 6 ]

2 голосов
/ 15 февраля 2010

В общем случае для числовых переменных (таких как счетчики циклов) следует использовать «int» и позволить компилятору выбрать наиболее эффективный размер для задачи. Если у вас есть особая потребность в конкретном размере (например, uint16 для 16-битной части заголовка пакета, получаемой из сети или подобного), тогда используйте typedef, который дает этот конкретный размер на вашей конкретной платформе; в противном случае просто используйте int.

Тем не менее, звучит так, как будто ваш учитель говорил о динамических распределителях памяти (то есть коде "malloc" и "free"). Например, если вы запрашиваете выделение 64 байта, распределитель отвечает за предоставление вам блока как минимум такого размера и отслеживание его, чтобы он мог быть возвращен в доступное хранилище после освобождения. Об этом много информации, например, в Википедии здесь: http://en.wikipedia.org/wiki/Dynamic_memory_allocation

0 голосов
/ 15 февраля 2010

Вероятно, ваш учитель имел в виду, что когда вы размещаете объект в куче (с new), весь процесс имеет тенденцию быть медленнее, чем больше объект. Я написал небольшую программу для измерения этого эффекта.

Вот результаты, которые я получаю (скомпилированные в режиме выпуска с VS2008 и отключенными оптимизациями):

Cost of allocating 1 chars: 0.104 microseconds
Cost of allocating 4 chars: 0.1 microseconds
Cost of allocating 16 chars: 0.104 microseconds
Cost of allocating 64 chars: 0.128 microseconds
Cost of allocating 256 chars: 0.192 microseconds
Cost of allocating 1024 chars: 0.416 microseconds
Cost of allocating 4096 chars: 1.28 microseconds
Cost of allocating 16384 chars: 2.56016 microseconds
Cost of allocating 65536 chars: 3.0722 microseconds
Cost of allocating 262144 chars: 3.58423 microseconds

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

0 голосов
/ 15 февраля 2010

На скорость записи и извлечения данных будет влиять производительность вашего локального механизма хранения. На современных процессорах есть регистры, 2 уровня кеша (L1 и L2), DRAM и иногда диск (через своп). Если шаблоны и размер доступа эффективно используют кэш L1 (то есть небольшой и локально согласованный), то, как только данные находятся в L1, их нужно только загрузить в регистры для доступа к ЦП. Если требуемые данные находятся в кеше L2, они должны быть сначала загружены в L1, а затем загружены в регистр для обработки. То же самое относится к DRAM к L2 к L1 к регистрам. Регистры быстрее, чем L1, L1 быстрее, чем L2, а DRAM просто медленный.

Херб Саттер выступил с докладом, посвященным этим вопросам, несколько лет назад на NWCPP:

http://video.google.com/videoplay?docid=-4714369049736584770#

С точки зрения программирования, если ваши данные могут помещаться в строке кэша и требуют многократного доступа или записи, у вас будет более высокая производительность из-за меньшего количества ошибок кэша (что приводит к необходимости извлечения из более высокого уровня кэша). ). Это верно для всех уровней «кэша», будь то регистры, L1, L2, DRAM, диск или удаленный сервер.

0 голосов
/ 15 февраля 2010

Одним из способов является использование типов переменных. Нет необходимости хранить значение от 1 до 10 в int64. Идея состоит в том, чтобы сопоставить возможные значения переменной с типом переменной, который наилучшим образом соответствует ее возможным значениям. Это сократит объем используемой памяти, а в более сложных структурах данных - скорость обработки.

0 голосов
/ 15 февраля 2010

Как хранить переменные редко зависит от вас. Но тип и, следовательно, размер переменной часто зависит от вас.

Возможно, он имел в виду такие вещи, как «если вам нужно сохранить маленькое целое число, например, уличный адрес, вам, вероятно, следует использовать не long, а short». Эти вещи, как правило, требуют немного знаний о предметной области, легко загнать себя в угол (например, подумать о проблеме 2000 года).

0 голосов
/ 15 февраля 2010

Вы имеете в виду постоянное хранение или выделение в памяти?

В памяти определяемая вами структура данных, способ выделения памяти для структуры данных (кучи или стека), используемый компилятор и совместно используемый стандарт C ++.

Постоянное хранение - это совсем другая история.

...