Форум: "Начинающим";
Текущий архив: 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