![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Оптимизация функции
Хинт © (2005-02-26 13:25:00)Написал функцию для проверки наличия строки в ListBox'е, который хранит имена файлов. Нужна для того, чтобы пользователь не мог добавить один и тот же файл дважды. В списке указано полное имя файла (C:\Temp\music.mp3). В списке в основном присутствуют более 1000 файлов. И проверка каждой новой строки занимает очень много времени.
Как можно оптимизировать функцию?
function TForm1.ExistsInList(Text:string):boolean;
var
i:integer;
begin
Result:=false;
if FListBox.Items.Count=0 then exit;
for i:=0 to FListBox.Items.Count-1 do
begin
if Length(Text)=Length(FListBox.Items[i]) then
if AnsiUpperCase(Text)=AnsiUpperCase(Flistbox.Items[i]) then
begin
Result:=true;
Break;
end;
end;
end;
Просто Джо (2005-02-27 21:21:00) [1]
> [18] Anatoly Podgoretsky © (27.02.05 21:12)
> Просто Джо © (27.02.05 21:10) [17]
> В списке указано полное имя файла (C:\Temp\music.mp3).
Ну, мало ли... Впрочем, похоже, что автор уже "оптимизировал" ([15]). Видимо, это был верх оптимизаторства. Никогда не знаешь, что человеку нужно.
Anatoly Podgoretsky (2005-02-27 21:12:00) [2]Просто Джо © (27.02.05 21:10) [17]
В списке указано полное имя файла (C:\Temp\music.mp3).
Просто Джо (2005-02-27 21:10:00) [3][12] reonid © (27.02.05 01:06)
В листбоксе Items это TStrings, а не TStringList
[14] Anatoly Podgoretsky © (27.02.05 10:46)
Задача поставлена так, что не ясно, можно ли сортировать визуальный список листбокса. Может, это плейлист какой-нибудь, и в нем как-раз строки должны быть неотсортированы, а находится в том порядке, в каком их расположит пользователь.
Хинт (2005-02-27 10:57:00) [4]function TForm1.ExistsInList(Text:string):boolean;
begin
Result:=(FListBox.Items.IndexOf(Text) >= 0);
end;
Всё оказалось намного проще, чем я думал....
А сравнивать, начиная с первого символа нет смысла. Так как в моем случае все строки начинается примерно с "D:\Music\Russian\..."
Хинт (2005-02-27 10:57:00) [5]function TForm1.ExistsInList(Text:string):boolean;
begin
Result:=(FListBox.Items.IndexOf(Text) >= 0);
end;
Всё оказалось намного проще, чем я думал....
А сравнивать, начиная с первого символа нет смысла. Так как в моем случае все строки начинается примерно с "D:\Music\Russian\..."
Anatoly Podgoretsky (2005-02-27 10:46:00) [6]reonid © (27.02.05 01:06) [12]
Да не важно, раз говорит нет, значит нет.
StarLit (27.02.05 01:08) [13]
А чего там писать одна строчка
if ListBox1.Items.IndexOf('строка') > -1 then ...
StarLit (2005-02-27 01:08:00) [7]>Хинт © (26.02.05 17:56) [6]
>Всем спасибо. Воспользовался IndexOf.
напиши как сделал , тоже надо сейчас делать...
reonid (2005-02-27 01:06:00) [8]У TStringList тоже есть Sorted.
Anatoly Podgoretsky (2005-02-26 23:27:00) [9]Зато у TListBox есть
TCustomListBox.Sorted
Specifies whether the items in a list box are arranged alphabetically.
programania (2005-02-26 22:11:00) [10]AnsiCompareText должно быть побыстрее
Еще можно сравнивать сначала первый знак строк
это одна команда CPU и если совпало,
то только тогда строки - это
куча команд с вызовом процедур.
Просто Джо (2005-02-26 22:00:00) [11]
> [8] Anatoly Podgoretsky © (26.02.05 18:08)
> Sorted и будет сверх-быстро
у TStrings нету Sorted
Anatoly Podgoretsky (2005-02-26 18:08:00) [12]Sorted и будет сверх-быстро
Просто Джо (2005-02-26 18:08:00) [13]
> но это почти что не влияет на скорость...
А делать все равно не стоит. Глаз режет.
Хинт (2005-02-26 17:56:00) [14]Всем спасибо. Воспользовался IndexOf.
2Просто Джо
Так тоже делал раньше, но это почти что не влияет на скорость...
Просто Джо (2005-02-26 15:12:00) [15]И еще, даже если "в лоб" делать, то запомни, что так делать никогда не нужно:
> if AnsiUpperCase(Text)=AnsiUpperCase(Flistbox.Items[i])
> then
Зачем каждый раз в цикле считать AnsiUpperCase(Text)? Достаточно один раз это сделать перед циклом, результат сохранить, а после сравнивать уже с ним.
TUser (2005-02-26 15:07:00) [16]шестая строчка - точно лишняя
Оптимизация - сделать список отсортированным и искать бинарно, за логарифмическое время. Если искать надо часто - то за n*log(n) ты его отсортируешь, а поиск будет быстрым. Если только один раз - наверное, надо при заполнении списка сделать какой-нибудь хеш.
Sam Stone (2005-02-26 14:13:00) [17]Pos(Text, ListBox.Items.Text)>0
XP (2005-02-26 13:42:00) [18](ListBox.Items.IndexOf(Text) >= 0)
или
(ListBox.Items.IndexOfName(Text) >= 0)
Anatoly Podgoretsky (2005-02-26 13:35:00) [19]IndexOf