![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Оптимизация кода (цикл в цикле), код ниже:
Yuraz © (2002-03-27 19:39:00)В Memo1 есть текст, раскладываю по буквам, переношу в Мemo2, каждую букву в новую строчку. Memo2 делаю Visible только после завершения цикла. Возможно ли как нибудь это всё ускорить, т.е. текст в 7000 знаков(7 кб) секунд десять перебирается.
procedure TForm1.SpeedButton1Click(Sender: TObject);
var i,j:integer;
a:string;
begin
for i:=0 to Memo1.Lines.Count-1 do
begin
for j:=1 to Length(Memo1.Lines[i]) do
begin
a:=Copy(Memo1.Lines[i],j,1);
Memo2.Lines.Add(a);
end; //for j
end; // for i
Memo2.Visible:=true;
end;
Anatoly Podgoretsky (2002-03-28 22:52:00) [1]Yuraz © (27.03.02 20:38)
S := ""; для Integer это не возможно
S := SetLength(Length(Memo1.Lines.Text)*3)
А здесь просто ошибка пропущено (s,
kull (2002-03-28 10:50:00) [2]Неплохо бы еще BeginUpdate и EndUpdate...
Alx2 (2002-03-28 09:33:00) [3]>amamed_3071 © (28.03.02 09:05)
Ваш вариант много медленнее предыдущего.
А вот это "Copy(Memo1.Lines[i],j,1)" быстрее сделать так Memo1.Lines[i][j]. И здесь лучше не использовать три операции конкатенации строк. Посимвольно в одну строку - быстрее.
amamed_3071 (2002-03-28 09:05:00) [4]procedure TForm1.SpeedButton1Click(Sender: TObject);
var i,j:integer;
a:string;
begin
A:="";
for i:=0 to Memo1.Lines.Count-1 do
begin
for j:=1 to Length(Memo1.Lines[i]) do
begin
a:=A+Copy(Memo1.Lines[i],j,1)+#13#10;
end; //for j
end; // for i
Memo2.Lines.Add(a);
Memo2.Visible:=true;
end;
Yuraz (2002-03-28 08:45:00) [5]Shaman_Naydak, работает действительно быстро, классно!
Shaman_Naydak (2002-03-27 21:06:00) [6]Ну поспешил человек, с кем не бывает..
Вот вариант Подгородецкого:
procedure TForm1.Button4Click(Sender: TObject);
var
S: string;
i, j: Integer;
begin
S := "";
if Length(Memo1.Lines.Text) <> 0 then begin
J := 1;
SetLength(S, Length(Memo1.Lines.Text)*3);
for I := 1 to Length(Memo1.Lines.Text) do begin
if Memo1.Lines.Text[I] >= " " then begin
S[J] := Memo1.Lines.Text[I];
S[J+1] := #13;
S[J+2] := #10;
J := J + 3;
end;
end;
end;
S[J] := #0;
Memo1.Lines.Text := PChar(@S[1]);
end;
А Вот и Мой вариант ( еще быстрее) :))
procedure TForm1.Button5Click(Sender: TObject);
var
S: string;
i: Integer;
P: PChar;
begin
S:=Memo1.Text;
if S = "" then
P:=PChar(S)
else
begin
i:=Length(S);
SetLength(S, i*3);
P:=PChar(@S[i*3])+1;
for i:=i downto 1 do
if S[i] >= " " then
begin
dec(P); P^:=#10;
dec(P); P^:=#13;
dec(P); P^:=S[i];
end;
end;
Memo1.Text:=P;
end;
wicked (2002-03-27 20:48:00) [7]напиши так - SetLength(s, Length(Memo1.Lines.Text))
Yuraz (2002-03-27 20:38:00) [8]s это string...
как, если SetLength - Integer?
wicked (2002-03-27 20:32:00) [9]s это string...
Yuraz (2002-03-27 20:31:00) [10]Anatoly Podgoretsky, s это string или integer? 1 и 4 строка ошибку выдаёт.
wicked (2002-03-27 20:16:00) [11]
> примерно 7000 раз перераспределяется
во как... а я не додул... хоть знал же, что оно так делает... :)
Anatoly Podgoretsky (2002-03-27 20:13:00) [12]Ерунда, надо сначало выделить необхожимую длину строки, а то она примерно 7000 раз перераспределяется
S := "";
if Length(Memo1.Lines.Text) = 0 then Exit;
J := 1;
S := SetLength(Length(Memo1.Lines.Text)*3)
for I := 1 to Length(Memo1.Lines.Text) do begin
if Memo1.Lines.Text[I] >= " " then begin
S[J] := Memo1.Lines.Text[I];
S[J+1] := #13;
S[J+2] := #10;
J := J + 3;
end;
end;
S[J] := #0;
Memo1.Lines.Text := PChar[S[1]];
Код не проверялся, но попробуй так.
wicked (2002-03-27 20:03:00) [13]да нет, можно и без асма... можешь попробовать использовать промежуточную стринговую переменную... например вместо
...Memo2.Lines.Text := Memo2.Lines.Text + Memo1.Lines.Text[i] + #13#10;
напиши
...s := s + Memo1.Lines.Text[i] + #13#10;
Memo2.Lines.Text := s;
Yuraz (2002-03-27 20:02:00) [14]Вот так, почти что как вверхний пример, что тоже медлено:
for i := 1 to length(Memo1.Lines.Text) do
if Memo1.Lines.Text[i] > #31 then
Memo2.Lines.Add(Memo1.Lines.Text[i] + #13);
Yuraz (2002-03-27 19:56:00) [15]wicked!, спасибо, но твой пример медленее примерно в 5 раз, причём после 5000 циклов (этот же 7 кб файл) процесс идёт совсем медленно, 7000 знаков разложил за секунд 25, верхний пример, засёк точно, за 5 секунд. У меня C766/196. Может тут выход только в асемблере?
wicked (2002-03-27 19:50:00) [16]например так:
Memo2.Lines.Clear;
for i := 1 to length(Memo1.Lines.Text) do
if Memo1.Lines.Text[i] > #31 then
Memo2.Lines.Text := Memo2.Lines.Text + Memo1.Lines.Text[i] + #13#10;