Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.04.11;
Скачать: CL | DM;

Вниз

Оптимизация кода (цикл в цикле), код ниже:   Найти похожие ветки 

 
Yuraz ©   (2002-03-27 19:39) [0]

В 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;


 
wicked ©   (2002-03-27 19:50) [1]

например так:

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;


 
Yuraz ©   (2002-03-27 19:56) [2]

wicked!, спасибо, но твой пример медленее примерно в 5 раз, причём после 5000 циклов (этот же 7 кб файл) процесс идёт совсем медленно, 7000 знаков разложил за секунд 25, верхний пример, засёк точно, за 5 секунд. У меня C766/196. Может тут выход только в асемблере?


 
Yuraz ©   (2002-03-27 20:02) [3]

Вот так, почти что как вверхний пример, что тоже медлено:

for i := 1 to length(Memo1.Lines.Text) do
if Memo1.Lines.Text[i] > #31 then
Memo2.Lines.Add(Memo1.Lines.Text[i] + #13);


 
wicked ©   (2002-03-27 20:03) [4]

да нет, можно и без асма... можешь попробовать использовать промежуточную стринговую переменную... например вместо
...Memo2.Lines.Text := Memo2.Lines.Text + Memo1.Lines.Text[i] + #13#10;

напиши
...s := s + Memo1.Lines.Text[i] + #13#10;
Memo2.Lines.Text := s;


 
Anatoly Podgoretsky ©   (2002-03-27 20:13) [5]

Ерунда, надо сначало выделить необхожимую длину строки, а то она примерно 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:16) [6]


> примерно 7000 раз перераспределяется


во как... а я не додул... хоть знал же, что оно так делает... :)


 
Yuraz ©   (2002-03-27 20:31) [7]

Anatoly Podgoretsky, s это string или integer? 1 и 4 строка ошибку выдаёт.


 
wicked ©   (2002-03-27 20:32) [8]

s это string...


 
Yuraz ©   (2002-03-27 20:38) [9]

s это string...
как, если SetLength - Integer?


 
wicked ©   (2002-03-27 20:48) [10]

напиши так - SetLength(s, Length(Memo1.Lines.Text))


 
Shaman_Naydak ©   (2002-03-27 21:06) [11]

Ну поспешил человек, с кем не бывает..
Вот вариант Подгородецкого:
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;


 
Yuraz ©   (2002-03-28 08:45) [12]

Shaman_Naydak, работает действительно быстро, классно!


 
amamed_3071 ©   (2002-03-28 09:05) [13]

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;


 
Alx2 ©   (2002-03-28 09:33) [14]

>amamed_3071 © (28.03.02 09:05)
Ваш вариант много медленнее предыдущего.
А вот это "Copy(Memo1.Lines[i],j,1)" быстрее сделать так Memo1.Lines[i][j]. И здесь лучше не использовать три операции конкатенации строк. Посимвольно в одну строку - быстрее.


 
kull ©   (2002-03-28 10:50) [15]

Неплохо бы еще BeginUpdate и EndUpdate...


 
Anatoly Podgoretsky ©   (2002-03-28 22:52) [16]

Yuraz © (27.03.02 20:38)

S := ""; для Integer это не возможно

S := SetLength(Length(Memo1.Lines.Text)*3)
А здесь просто ошибка пропущено (s,



Страницы: 1 вся ветка

Текущий архив: 2002.04.11;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.014 c
1-32812
abstek
2002-03-30 10:42
2002.04.11
Как узнать тип переменной?


7-32992
Jazzy$
2002-01-18 16:41
2002.04.11
Добвить кнопку к окну


14-32969
oblom
2002-03-05 14:36
2002.04.11
задание в универе


3-32620
BigError
2002-03-22 13:23
2002.04.11
Определение количества записей в физической таблице, несмотря на фильтрацию


1-32842
guood
2002-03-28 17:46
2002.04.11
Рабочая директория приложения