Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.12.26;
Скачать: CL | DM;

Вниз

Проблема с процедурой   Найти похожие ветки 

 
v_a_belousov   (2010-10-01 03:14) [0]

Здравствуйте! Есть процедура

procedure TReaderMainForm.AddFileToList(List: TStrings; const SFileName: String);
//переменные
var CText: string;
begin
//проверяем тип файла
if GetFileTypeAtExt(ExtractFileExt(SFileName))<>EmptyType then
begin
 // Добавляем после проверки - есть там уже такое имя или нет
 if List.IndexOf(ExtractCName(ExtractFileName(SFileName))) = -1 then
  begin
   //очищаем переменную
   CText := VPlayList.CommaText;
   List.Add(ExtractCName(ExtractFileName(SFileName)));
   //указываем
   VPlayList.NameValueSeparator := "=";
   //если в переменную ещё ничегго не записано, то
   if CText<>"" then //такой вид записи не подходит
   CText := CText + ", " + """ + ExtractFileName(SFileName) + "=" +
   SFileName + """ else //значит пишем так
   CText := """ + ExtractFileName(SFileName) + "=" + SFileName + """;
   //добавляем в список
   VPlayList.CommaText := CText;
  end;
end;
end;

вот сразу код сопутствующей функции
function TReaderMainForm.GetFileTypeAtExt(FExt: string): TFileType;
var i: integer; //счетчик
begin
//ищем заданное расширение среди видеотипов
for i:=0 to Length(VideoExts)-1 do
begin
 //если найден, то
 if AnsiUpperCase(VideoExts[i]) = AnsiUpperCase(FExt) then
  begin
   //сообщаем что это видеофайл
   result := VideoType;
   //выходим
   exit;
  end;
end;
//ищем заданное расширение среди аудиотипов
for i:=0 to Length(AudioExts)-1 do
begin
 //если найден, то
 if AnsiUpperCase(AudioExts[i]) = AnsiUpperCase(FExt) then
  begin
   //сообщаем что это аудиофайл
   result := AudioType;
   //выходим
   exit;
  end;
end;
//ищем заданное расширение среди графических типов
for i:=0 to Length(PictureExts)-1 do
begin
 //если найден, то
 if AnsiUpperCase(PictureExts[i]) = AnsiUpperCase(FExt) then
  begin
   //сообщаем что это графический файл
   result := PictureType;
   //выходим
   exit;
  end;
end;
//если не совпадает не с одним из вышеперечисленных, то значит пусто
Result := EmptyType;
end;

В цикле добавляю файлы в список

 //добавляем файлы из папок и их подпапок в список
 for i:=0 to DropFiles_List.Count-1 do
  begin
   //добавляем имя в список
   ReaderMainForm.AddFileToList(ReaderMainForm.PlayList_LB.Items, DropFiles_List.Strings[i]);
   //Не даем зависнуть
   Application.ProcessMessages;
  end;

Проблема в том что примерно после 17000 файлов которые добавляются за пару секунд до 18000 файлов проходит уже секунд 30 а до 18500 файлов тратится ещё почти минута. Подскажите пожалуйста что я не правильно делаю.


 
v_a_belousov   (2010-10-01 03:42) [1]

хотел бы уточнить. Файлы добавляются переносом из проводника(если папка, то производится поиск файлов во всех подпапках). Попробовал сейчас перенести диск D на ListBox зависло на 9000(из 16000) файлов, с диска E на 17000(из 94000) файлов а с диска F за пару секунд перенес 21000 файлов(все найденные).


 
MBo ©   (2010-10-01 06:00) [2]

Всё не смотрел, но поиск IndexOf для больших списков медленный. Да еще и в визуальном компоненте.
Сортированный TStringList + Find

Кроме того, для каждого файла в CommaText и назад, насколько я понял, гоняется большая строка. Это необходимо? Что там за логика подразумевается?


 
Apollo   (2010-10-01 07:09) [3]

Такие объемы лучше грузить не в линейный список, а использовать какую-то структуру, по типу древовидной, чтобы ограничивать объем одновременно загружаемых и выводимых данных.

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

Но если и этого не хочется, то не вызывай так часто Application.ProcessMessages, делай один вызов на 10, 100 добавлений:
if i mod 100 = 0 then
 Application.ProcessMessages;


Кроме того, перед циклом добавления можно вызвать ListBox.Items.BeginUpdate, а после цикла - ListBox.Items.EndUpdate. Это заблокирует визуальное обновление списка на время добавления, что ускорит весь процесс. Хотя, может, тебе нравятся визуальные эффекты при загрузке списка...

Еще, у тебя несколько раз встречается вызов  ExtractCName(), ExtractFileName(). Заведи в методе добавления пару локальных переменных, в самом начале метода один раз выполни FN := ExtractFileName() и CN := ExtractCName(FN) (кстати, что это за функция?), и пользуйся далее полученными значениями.

Еще замечания по поводу AnsiUpperCase(VideoExts[i]) = AnsiUpperCase(FExt).
VideoExts (как и другие списки расширений) у тебя уже заранее должны быть в верхнем регистре, чтобы не выполнять при каждо проверке преобразование.

Мне я ошибаюсь, но мне кажется, что здесь много лишней работы: CText := VPlayList.CommaText;... (и прочие движения с CommaText). Может, сделать вот так: VPlayList.Values[FN] := SFileName?

В общем, логика работы по добавлению файлов мне не совсем понятна. Если уточнишь, может, будут другие советы. А пока извини, если что не так...


 
RWolf ©   (2010-10-01 09:57) [4]

насколько я понимаю, принципиальная ошибка здесь в использовании наследника TStrings — контейнера со временем поиска O(n) — для хранения данных вида "имя-значение"; здесь больше подошло бы что-то вроде хэш-таблицы (см. библиотеку Delphi Fundamentals, например).



Страницы: 1 вся ветка

Текущий архив: 2010.12.26;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.008 c
15-1284430430
AlexDn
2010-09-14 06:13
2010.12.26
PayPal


2-1285698321
Levan
2010-09-28 22:25
2010.12.26
Findfirst() в Делфи10


15-1284451837
Kolan
2010-09-14 12:10
2010.12.26
Аналог Apple Core Animation для Делфи


15-1279267909
_L_
2010-07-16 12:11
2010.12.26
Помоготе найти заголовочный файл Dwmapi...


15-1284409769
Юрий
2010-09-14 00:29
2010.12.26
С днем рождения ! 14 сентября 2010 вторник