Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.12.26;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.003 c
2-1286133494
Sperry
2010-10-03 23:18
2010.12.26
"обратный цыкл"


2-1285857008
faiwer
2010-09-30 18:30
2010.12.26
Уничтожение объекта


3-1250065947
RDen
2009-08-12 12:32
2010.12.26
Доброго всем времени суток.


15-1284562752
Unknown_user
2010-09-15 18:59
2010.12.26
Написание собственного COM сервера автоматизации


2-1286134005
v_a_belousov
2010-10-03 23:26
2010.12.26
Обращение к группе объектов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский