Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Экономия памяти с дублирующими значениями в таблице

Delphi , Базы данных , Таблицы

Экономия памяти с дублирующими значениями в таблице

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{ 
  Often there are lots of duplicate strings in a program, 
  for example take the following database: 

  Author    Title 
  aaa        xxx 
  aaa        yyy 
  aaa        zzz 

  Suppose you want to read it into your program and 
  create one record or class per line: 
}

 while not Table.EOF do
 begin
   author := Table['Author'];
   title := Table['Title'];
   MyClass := TMyClass(author, title);
   StoreItSomewhere(MyClass);
   Table.Next;
 end;

 { 
  You end up with three different strings containting the same author. 
  No problem with that as long as there are only three of them. 
  Now suppose you have got a database of 100,000 entries and lots of 
  duplicate author names. 
  If you do the above again you will end up with a huge memory overhead 
  due to fragmentation of the free memory on the heap. 
  In addition to that freeing the objects will result in a noticable delay 
  of the program while the memory manager is busy merging free memory blocks. 
  On the other hand, Delphi's AnsiStrings use reference counting so it 
  would be possible to assign the same string to many string variables 
  without copying the contents: 
}

 Author := 'aaa';
 for i:=0 to 100000 do
 begin
   MyClass := TMyClass(Author);
   StoreItSomewhere(MyClass);
 end;

 { 
  This will create 100000 strings containting 'aaa', 
  but store the actual contents only once, 
  because they are assigned the same string constant. 

  It would be nice to do the same with the above database example, 
  wouldn't it? But how do we get Delphi to realize that 
  the content is really the same? 

  Answer: A StringList 
}

 authors := TStringList.Create;
 authors.Sorted := true;
 authors.Duplicates := dupIgnore;
 while not Table.EOF do
 begin
   author := Table['Author'];
   title := Table['Title'];

   authors.Add(author);
   authors.Search(author, Idx);
   author := authors[Idx];

   MyClass := TMyClass(author, title);
   StoreItSomewhere(MyClass);
   Table.Next;
 end;
 authors.free;

 { 
  This will only keep one string of each author's name and assign 
  it to all other occurences, even after the StringList has been freed again. 
  The wonders of reference counting! 

  I admit that the above example looks a bit odd. Nobody would load 
  such a database into memory. But I had a similar problem today and by using 
  the trick above I managed to reduce the memory usage of my program from 120 megabytes to 10 
  (basically nothing, given that it started out with 8 mb). 
}

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

Автор затем представляет решение, использующее объект StringList. StringList - это структура данных, позволяющая хранить строки в списке и управлять дубликатами строк. Установка свойства Sorted в True позволяет StringList автоматически удалять дубликаты из списка. Свойство Duplicates может быть установлено в either dupIgnore, игнорируя дубликаты, или dupError, выдавая ошибку при обнаружении дубликата.

Автор использует это решение для загрузки базы данных в память и создания объектов для каждой записи в базе. Используя StringList для управления дубликатами строк, программа может уменьшить свой занимаемый объем памяти значительно.

Вот разбивка кода:

var
  authors: TStringList;
begin
  authors := TStringList.Create;
  try
    authors.Sorted := True;
    authors.Duplicates := dupIgnore;

    while not Table.EOF do begin
      author := Table['Author'];
      title := Table['Title'];

      authors.Add(author);
      authors.Search(autor, Idx);
      autor := authors[Idx];

      MyClass := TMyClass.Create(author, title);
      StoreItSomewhere(MyClass);
      Table.Next;
    end;

  finally
    authors.Free;
  end;
end;

Класс TStringList является частью Delphi VCL (Visual Component Library) и предоставляет способ хранения строк в списке. Свойство Sorted specifies, whether the list should be sorted or not, and the Duplicates property specifies how duplicate entries should be handled.

В этом примере автор создает новый объект TStringList и устанавливает его свойства в Sorted=True и Duplicates=dupIgnore. Затем они загружают базу данных в память с помощью цикла, который читает каждую запись из таблицы и добавляет ее в StringList.

Метод Search используется для поиска индекса автора в списке. Если автор уже присутствует в списке, этот метод вернет индекс первого вхождения; иначе, он добавит автора в конец списка.

Наконец, автор создает новый экземпляр класса TMyClass с помощью загруженной информации и хранит его где-то (например, в памяти или на диске). Цикл продолжается до тех пор, пока не будут обработаны все записи из таблицы.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Таблицы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-06 02:21:36/0.0035970211029053/0