Правила программирования на С и С++. Главы 1-6 - Динамическая память - дорогое удовольствие
ОГЛАВЛЕНИЕ
Страница 81 из 93
74. Динамическая память - дорогое удовольствие.
Следующей основной проблемой при использовании malloc()/ free() (или new/delete) является время, требуемое для управления памятью; оно может быть значительным. Я однажды сократил время выполнения на 50% путем замены многочисленных вызовов malloc() и free() на другую стратегию. Например, если у вас есть очень активно используемая структура из одинаковых объектов, то вы можете использовать нечто подобное коду из листинга 4 для управления членами структуры данных.
Листинг 4. Управление собственным списком высвобожденных элементов.
- typedef struct some_class
- {
- struct some_class *next;
- //...
- }
- some_class;
- static some_class *free_list = NULL;
- //-------------------------------------------------------------------------------------------------------------------------------------------
- free_object( some_class *object )
- {
- // Вместо того, чтобы передать память из-под объекта функции free(),
- // свяжите ее с началом списка высвобожденных элементов.
- object->next = free_list;
- free_list = object;
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------
- free_all_objects( )
- {
- // Высвободить все объекты в список высвобожденных элементов. Сортировка
- // этих объектов по базовому адресу перед началом цикла улучшит скорость работы
- // по освобождению, но я не делаю здесь этого. (Для сортировки связанных
- // списков превосходно подходит алгоритм Quicksort).
- some_object *current;
- while ( free_list )
- {
- current = free_list;
- free_list = current->next;
- free( current );
- }
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------
- some_class *new_object( )
- {
- // Если в списке высвобожденных элементов имеется объект, то используйте
- // его. Размещайте объект посредством malloc(), только если список
- // высвобожденных объектов пуст.
- some_class *object;
- if ( free_list )
- {
- object = free_list; // передайте память для объекта
- free_list = object->next;
- }
- else
- {
- // Вы можете улучшить производительность еще более, если будете
- // размещать объекты в памяти по 100, а не по 1 за раз, но это усложнит
- // функцию free_all_objects().
- object = malloc( sizeof(some_class) );
- }
- if ( object )
- // поместите здесь инициализирующий код
- return object;
- }