Главная страница
    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-1286010174
Mihelson
2010-10-02 13:02
2010.12.26
Парсер текста со скобками (круглыми, фигурными и проч.)


2-1285851032
coder123
2010-09-30 16:50
2010.12.26
Как найти открытую форму по типу и по части названия?


2-1285805956
HF-Trade
2010-09-30 04:19
2010.12.26
Назначить диапазону массива значения


15-1284634047
Kerk
2010-09-16 14:47
2010.12.26
Обладателям девайсов на Android


8-1208783409
Музыкант
2008-04-21 17:10
2010.12.26
Сэмплирование midi файла





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский