Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.02.2013, 15:32   #11
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
Весь ступор происходит при заполнении Dictionary
А dictionary то же выделяет себе память.(ему же надо хранить все это) И тоже много раз. И тоже хапаем много. при отсутствии повторов!

И тоже много раз. Можно попробовать заставить его выделить сразу много.
Цитата:
Set Capacity to the number of pointers the list will need to contain. When setting the Capacity property, an EOutOfMemory exception occurs if there is not enough memory to expand the list to its new size.

Read Capacity to learn number of objects the list can hold without reallocating memory. Do not confuse Capacity with the Count property, which is the number of entries in the list that are in use. The value of Capacity is always greater than or equal to the value of Count. When Capacity is greater than Count, the unused memory can be reclaimed by setting Capacity to Count.

When an object is added to a list that is already filled to capacity, the Capacity property is automatically increased. Setting Capacity before adding objects can reduce the number of memory reallocations and thereby improve performance. For example,

Delphi example:
Код:
  List.Clear;
  List.Capacity := Count; // хотим сразу много
  for I := 1 to Count do List.Add(...);
А вообще-то для таких задач и используются БД.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 26.02.2013, 17:42   #12
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Да, эту инфу я тоже нашел вчера поздно вечером.
В общем как я понял из всего происходящего - дело именно в самой Dictionary, которая вообще не может хранить много ключей как таковых. При этом если честно не совсем понятно - почему же она в какие-то моменты становится на это способной? Но это все мусор и бред, т.к. стабильности не добиться.
Есть у меня вариант и проще по памяти - основанный не на записях, а на классах, когда точки хранятся в листе (нет проблем и для моих 34 млн), а в качестве ключа генерится простой хэшкод.
Там происходит все немного иначе - из листа, в котором уже есть все точки, удаляются ненужные. Выпадает Out of Memory именно на заполнении Dictionary, примерно на 3 млн. - специально вчера проверил:
Код:
  Dictionary := TDictionary<TBinPoints, Integer>.Create(Comparer);
    Form1.Memo2.Lines.Add('Dictionary is ready');
  try
    for I := Points.Count - 1 downto 0 do //
      begin
        if Dictionary.ContainsKey(Points[I]) then
           Points.Delete(I)
        else
          Dictionary.Add(Points[I], 0);
      end;
    Dictionary.Free;
  except
    On E : EOutOfMemory do
    begin
      ShowMessage(IntToStr(Dictionary.Count));
      Dictionary.Free;
    end;
  end;
Вообще сама задача решается как-то и без БД и без Dictionary, есть у меня пример этого (готовая прога), но как там это реализовано - одному Богу известно. Просто в отличии от ее создателя я не являюсь продвинутым программистом с весомым багажом знаний.
Будет время - попробую на БД, потом отпишусь как результат.
Freimaks вне форума Ответить с цитированием
Старый 12.03.2013, 13:52   #13
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Что самое прикольное - прога отлично заработала при компиляции 64-битным компилятором... спокойно обрабатываются файлы более гигабайта...
Freimaks вне форума Ответить с цитированием
Старый 12.03.2013, 14:56   #14
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

у тебя 2 буфера зачем? чтение позаписьно медленно?

Код:
procedure WorkWithCoordTimes(FileName: String);
var i, TotalCount, Count, ControlCount:integer;
BinKey: SizeBinKey; //переменная для формирования ключа
BinItem: SizeBinItem; //переменная для формирования значения
BinPoint:SizeBinPoints; //запись
const MAX_BUFFER_SIZE = 10000000; //В массив за один раз загоняется не более 10 млн. записей, каждая 24 байта
begin
  with TBinaryReader.Create(FileName) do
    try
      Dictionary := TDictionary<SizeBinKey, SizeBinItem>.Create;
      BaseStream.Read(BinHeader, SizeOf(BinHeader));
      TotalCount:=BinHeader.PntCnt;
      while TotalCount > 0 do
        begin
          BaseStream.Read(BinPoint, SizeOf(BinPoint));
          BinKey.X:=BinPoint.X;
          BinKey.Y:=BinPoint.Y;
          BinKey.Z:=BinPoint.Z;
          BinKey.Time:=BinPoint.Time;
          BinItem.Code:=BinPoint.Code;
          BinItem.Echo:=BinPoint.Echo;
          BinItem.Flag:=BinPoint.Flag;
          BinItem.Mark:=BinPoint.Mark;
          BinItem.Line:=BinPoint.Line;
          BinItem.Int:=BinPoint.Int;
          Dictionary.AddOrSetValue(BinKey,BinItem);
          Dec(TotalCount);
        end;
        Form1.Memo1.Lines.Add(IntToStr(Dictionary.Count)) ;
      end;
    finally
      Free;
    end;
  end;
end.
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 12.03.2013, 15:16   #15
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Я специально для экспериментов вынес размер буфера в переменные и задаю его из отдельного поля.
Если читать по одной записи, то чтение файла 655 Мб и прогон в Dictionary проходит за 34757 мсек.
Если читать по 1000 записей за раз, то такая же операция проходит за 10983 мсек. Если по 10000, то 9422 мсек.
Freimaks вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Load exe into memory and run it from memory artush1984 Win Api 10 06.02.2012 18:43
Правильная работа с формами CodeNOT PHP 5 12.04.2011 12:34
Правильная работа скрола в панели. evilgeniuz Общие вопросы .NET 0 29.09.2010 00:17
Правильная работа условия if Andruha10 PHP 1 22.08.2010 21:23
Не правильная работа for .. to Neptunium Общие вопросы Delphi 7 05.04.2010 00:32