Правила программирования на С и С++. Главы 1-6 - Динамическая память - дорогое удовольствие

ОГЛАВЛЕНИЕ

74. Динамическая память - дорогое удовольствие.

Следующей основной проблемой при использовании malloc()/ free() (или new/delete) является время, требуемое для управления памятью; оно может быть значительным. Я однажды сократил время выполнения на 50% путем замены многочисленных вызовов malloc() и free() на другую стратегию. Например, если у вас есть очень активно используемая структура из одинаковых объектов, то вы можете использовать нечто подобное коду из листинга 4 для управления членами структуры данных.

Листинг 4. Управление собственным списком высвобожденных элементов.

  1. typedef struct some_class
  2. {
  3. struct some_class *next;
  4. //...
  5. }
  6. some_class;
  7. static some_class *free_list = NULL;
  8. //-------------------------------------------------------------------------------------------------------------------------------------------
  9. free_object( some_class *object )
  10. {
  11. // Вместо того, чтобы передать память из-под объекта функции free(),
  12. // свяжите ее с началом списка высвобожденных элементов.
  13. object->next = free_list;
  14. free_list = object;
  15. }
  16. //-------------------------------------------------------------------------------------------------------------------------------------------
  17. free_all_objects( )
  18. {
  19. // Высвободить все объекты в список высвобожденных элементов. Сортировка
  20. // этих объектов по базовому адресу перед началом цикла улучшит скорость работы
  21. // по освобождению, но я не делаю здесь этого. (Для сортировки связанных
  22. // списков превосходно подходит алгоритм Quicksort).
  23. some_object *current;
  24. while ( free_list )
  25. {
  26. current = free_list;
  27. free_list = current->next;
  28. free( current );
  29. }
  30. }
  31. //-------------------------------------------------------------------------------------------------------------------------------------------
  32. some_class *new_object( )
  33. {
  34. // Если в списке высвобожденных элементов имеется объект, то используйте
  35. // его. Размещайте объект посредством malloc(), только если список
  36. // высвобожденных объектов пуст.
  37. some_class *object;
  38. if ( free_list )
  39. {
  40. object = free_list; // передайте память для объекта
  41. free_list = object->next;
  42. }
  43. else
  44. {
  45. // Вы можете улучшить производительность еще более, если будете
  46. // размещать объекты в памяти по 100, а не по 1 за раз, но это усложнит
  47. // функцию free_all_objects().
  48. object = malloc( sizeof(some_class) );
  49. }
  50. if ( object )
  51. // поместите здесь инициализирующий код
  52. return object;
  53. }