Динамическая память — дорогое удовольствие
Следующей основной проблемой при использовании malloc()/free()
(или new/delete)
является время, требуемое для управления памятью; оно может быть значительным. Я однажды сократил время выполнения на 50% путем замены многочисленных вызовов malloc() и
free() на другую стратегию. Например, если у вас есть очень активно используемая структура из одинаковых объектов, то вы можете использовать нечто подобное коду из листинга 4 для управления членами структуры данных.
Листинг 4.
Управление собственным списком высвобожденных элементов
typedef struct
some_class
{
struct some_class *next;
//...
}
some_class;
/p>
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;
}