Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> StringList, неужели такой тормоз? 
:(
    Опции темы
z-END
Дата 23.1.2005, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Вот тестовая прога, ничего умного она не делает=) просто засекает время выполнения двух вещей:
1. Добавление элементов в StringList
2. Получение индекса сторки из StringList
Вообщем я впал в ужас..
Код

program testCons;

{$APPTYPE CONSOLE}
uses
 SysUtils, Classes, Windows, Forms;
var
Found, Added, Steps, x, startIdx, finishIdx, startAdd, finishAdd: Integer;
List: TStringList;
begin
Randomize;
Repeat
 Write ('Enter cycle steps (0 for exit): ');
 Readln (Steps);
  if Steps > 0 then
    begin
     Dec (Steps);
     Write ('Adding List...');
     List := TStringList.Create;
     Added := 0;
     StartAdd := GetTickCount;
      for x := 0 to Steps do
        begin
          List.Add (IntToStr( Random(MaxInt)));
           Application.ProcessMessages;
          Inc (added);
        end;
     finishAdd := GetTickCount;
     Writeln ('  complete.');
     Write ('Getting index...');
     Found := 0;
     StartIdx := GetTickCount;
     for x := 0 to Steps do
       begin
         Application.ProcessMessages;
          if List.IndexOf(IntToStr(x))=-1 then Continue;
         Inc(found);
       end;
     finishIdx := GetTickCount;
     Writeln ('  complete.');
     Writeln ('Result:');
     Writeln ('Adding time: ' + IntToStr (finishAdd - startAdd) + ' ms');
     Writeln ('Indexing time: ' + IntToStr (finishIdx - startIdx) + ' ms');
     Writeln ('Added: ' + IntToStr (Added));
     Writeln ('Matches: ' + IntToStr (Found));
     Writeln ('----------------------------------------------------');
     Freeandnil (List);
  end;
Until Steps = 0
end.


Кому лень запускать привожу результаты работы:

Цитата
Enter cycle steps (0 for exit): 1000
Adding List...  complete.
Getting index...  complete.
Result:
Adding time: 0 ms
Indexing time: 734 ms
Added: 1000
Matches: 0
----------------------------------------------------
Enter cycle steps (0 for exit): 5000
Adding List...  complete.
Getting index...  complete.
Result:
Adding time: 16 ms
Indexing time: 18594 ms
Added: 5000
Matches: 0
----------------------------------------------------


Чуть про вопрос незабыл=)
возможно ли ускорить этот процесс? т.к. у меня в списке (запланировано) до 300 тыс. строк. smile
Да, индексирование я использую для определения наличия данной строки в списке, (все строки уникальны)
может есть более оптимальные варианты?


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Alex
Дата 23.1.2005, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162





--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
z-END
Дата 23.1.2005, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Alex анд что?


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Alex
Дата 23.1.2005, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Код

    Writeln ('  complete.');
    List.Sorted:= True;
    Write ('Getting index...');

Добавлено @ 12:39
Цитата(z @ 23.1.2005, 12:36)
Alex анд что?

Модуль дя более точного засекания времени
Добавлено @ 12:41
Цитата
Enter cycle steps (0 for exit): 65535             
Adding List...  complete.                         
Getting index...  complete.                       
Result:                                           
Adding time: 79 ms                                 
Indexing time: 516 ms                             
Added: 65535                                       
Matches: 3                                         
----------------------------------------------------
Enter cycle steps (0 for exit):                   



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
z-END
Дата 23.1.2005, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Слона-то я и не заметил=)

Alex, очередное спасибо!

ЗЫ, да мне точно и ненадо было, так просто сравнить разницу..

Это сообщение отредактировал(а) z-END - 23.1.2005, 12:43


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Alex
Дата 23.1.2005, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Причину знаешь почему так произошло?


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Петрович
Дата 23.1.2005, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 25
Всего: 55



Ну, тут как всегда. Очевидное решение не всегда самое эффективное. Давай, несколько модифицироуем твой приммер:
Код

program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Windows, Forms;
var
Found, Added, Steps, x, startIdx, finishIdx, startAdd, finishAdd: Integer;
List: TStringList;
S :String;
begin
Randomize;
Repeat
Write ('Enter cycle steps (0 for exit): ');
Readln (Steps);
 if Steps > 0 then
   begin
    Dec (Steps);
    Write ('Adding List...');
    List := TStringList.Create;
    Added := 0;
    StartAdd := GetTickCount;
     for x := 0 to Steps do
       begin
         List.Add (IntToStr( Random(MaxInt)));
          Application.ProcessMessages;
         Inc (added);
       end;
    finishAdd := GetTickCount;
    Writeln ('  complete.');
    Write ('Getting index...');

    s := ^M^J+List.Text;
    Found := 0;
    StartIdx := GetTickCount;
    for x := 0 to Steps do
      begin
        Application.ProcessMessages;
        if Pos(^M^J+IntToStr(x)+^M^J,s)=0 then Continue;
        Inc(found);
      end;
    finishIdx := GetTickCount;


    Writeln ('  complete.');
    Writeln ('Result:');
    Writeln ('Adding time: ' + IntToStr (finishAdd - startAdd) + ' ms');
    Writeln ('Indexing time: ' + IntToStr (finishIdx - startIdx) + ' ms');
    Writeln ('Added: ' + IntToStr (Added));
    Writeln ('Matches: ' + IntToStr (Found));
    Writeln ('----------------------------------------------------');
    Freeandnil (List);
 end;
Until Steps = 0
end.
Теперь сравним результаты:
До модификации:
Цитата
Enter cycle steps (0 for exit): 5000
Adding List...  complete.
Getting index...  complete.
Result:
Adding time: 0 ms
Indexing time: 15343 ms
Added: 5000
Matches: 0

После:
Цитата
Enter cycle steps (0 for exit): 5000
Adding List...  complete.
Getting index...  complete.
Result:
Adding time: 0 ms
Indexing time: 2125 ms
Added: 5000
Matches: 0

А еще:
1. Application.ProcessMessages в консольных приложениях - это лишнее.
2. Нужно выносить действия инвариантные к циклу, за его пределы.
Но это ты уже сам smile


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
z-END
Дата 23.1.2005, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Alex чесно говоря несовсем=)
так-что c радостью готов услышать!

Петрович ProccessMessages я использовал только для того чтобы приблизить результаты к другой софтине, которая совершенно не консольная=) (кстати в ней то-же код работает намного медленней)
а вот про второй пункт я несовсем понялsmile

ЗЫ а вот результат сортировонного списка:
Цитата
Enter cycle steps (0 for exit): 5000
Adding List...  complete.
Getting index...  complete.
Result:
Adding time: 16 ms
Indexing time: 32 ms
Added: 5000
Matches: 0
----------------------------------------------------



--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Alex
Дата 23.1.2005, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



1 Ссылка на модуль для замера времени исполнения теперь http://vingrad.ru/DELPHI-SRC-002244


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Петрович
Дата 23.1.2005, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 25
Всего: 55



Цитата(z @ 23.1.2005, 14:06)
ЗЫ а вот результат сортировонного списка

Ну да, в отсортированном конечно поиск быстрее. Всетаки используется алгоритм QuickSearch smile
Цитата(z @ 23.1.2005, 14:06)
а вот про второй пункт я несовсем понял

Я имел ввиду что преобразование IntToStr тоже занимает чувствительнгое время, хотя совершено не имеет отношения к исследуемой функции. Если его вынести за пределы цикла, например подготовив зарание массив испкомых строк, то работать будет несколько быстрее. Но все равно, лвиную долю времени занимает конечно поиск.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Alex
Дата 23.1.2005, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Цитата(z @ 23.1.2005, 13:06)
Alex чесно говоря несовсем=)
так-что c радостью готов услышать!

Дело в том, что если посмотреть на реализацию метода IndexOf, то можно увидеть, что в нем по-разному происходит поиск в отсортированном и не отсортированном списке
Код

function TStringList.IndexOf(const S: string): Integer;
begin
 if not Sorted then Result := inherited IndexOf(S) else
   if not Find(S, Result) then Result := -1;
end;


Если список, не отсортированный, то дергается базовый метод типа TStrings
Код

function TStrings.IndexOf(const S: string): Integer;
begin
 for Result := 0 to GetCount - 1 do
   if CompareStrings(Get(Result), S) = 0 then Exit;
 Result := -1;
end;

Он не эффективен по той причине, что постоянно идет перебор всех элементов списка.

Если же сортировка включена, то выборку можно осуществить гораздо быстрее по методу деления по полам. Это когда весь ОТСОРТИРОВАННЫЙ массив бьется на 2 и определяется, к какой части относится элемент, который ищут. Дальше эту уже часть опять делят на 2 и так далее пока не найдут нужный элемент.
Код

function TStringList.Find(const S: string; var Index: Integer): Boolean;
var
 L, H, I, C: Integer;
begin
 Result := False;
 L := 0;
 H := FCount - 1;
 while L <= H do
 begin
   I := (L + H) shr 1;
   C := CompareStrings(FList^[I].FString, S);
   if C < 0 then L := I + 1 else
   begin
     H := I - 1;
     if C = 0 then
     begin
       Result := True;
       if Duplicates <> dupAccept then L := I;
     end;
   end;
 end;
 Index := L;
end;



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0961 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.