Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

заранее задать размер строки Setlength ?


Страницы:   1 2

Den ©   (2012-04-08 00:21:00) 

задача: ускорить выполнение кода.
есть 2 переменные s, s1:string; заранее известно что length(s1) не будет больше length(s)*2.

ну и собственно код:

while length(s)>0 do begin
s1:=s1+copy(s, 1,1)+'a';
delete(s,1,1);
end;

если заранее задать размер s1 вот так
setlength(s1, length(s)*2);
а потом присвоить значение
s1:='';
это обнулит ее length или нет? То есть будет ли s1 перезаписываться в другое место в памяти если ей начать присваивать какие-то значения?


Den   (2012-04-09 11:27:00) [1]

Ну я в нее ем:)


oldman   (2012-04-09 10:25:00) [2]


> а потом присвоить значение
> s1:='';
> это обнулит ее length или нет?


МАМА!!! РОДИ МЕНЯ ОБРАТНО!!!
Извините за грубость, но голова на что?


Den   (2012-04-09 08:51:00) [3]

MBo Спасибо!


MBo   (2012-04-09 08:46:00) [4]

s := '12345';
 s3 := 'ddddd';
 l3 := Length(s3);
 l3p1 := l3 + 1;
 SetLength(s1, Length(s) * l3p1);
 for i := 0 to Length(s) - 1 do begin
   s1[1 + i * l3p1] := s[i + 1];
   Move(s3[1], s1[2 + i * l3p1], l3 * SizeOf(Char));
 end;


Den   (2012-04-09 08:39:00) [5]

маленькое уточнение не суть конечно но всетаки

procedure TForm1.Button1Click(Sender: TObject);
var
s,s1,s3:string;
i,i1,i2:integer;
begin
s:='12345';
s3:='ddddd';
setlength(s1,length(s)+length(s)*length(s3));
i1:=1;
for i:=1 to length(s) do begin
s1[i1]:=s[i];
s1[i1+1]:='d';
for i2:=1 to length(s3) do begin
s1[i1+i2]:=s3[i2];
end;
inc(i1,length(s3)+1);
memo1.lines.Add(s1);
end;
end;


Den   (2012-04-09 08:32:00) [6]

Так наверное можно:
procedure TForm1.Button1Click(Sender: TObject);
var
s,s1,s3:string;
i,i1,i2:integer;
begin
s:='12345';
s3:='ddddd';
setlength(s1,length(s)*length(s3));
i1:=1;
for i:=1 to length(s) do begin
s1[i1]:=s[i];
s1[i1+1]:='d';
for i2:=1 to length(s3) do begin
s1[i1+i2]:=s3[i2];
end;
inc(i1,length(s3));
memo1.lines.Add(s1);
end;
end;

насчет быстродействия чет правда сомневаюсь, надо проверить как-то...


Den   (2012-04-09 07:48:00) [7]


> Setlength(s1, Length(s) * 2);
> for i := 1 to Length(s) do begin
>  s1[2 * i - 1] :=s[i];
>  s1[2 * i] := 'a';
> end;


А как добавить к примеру не 'a' а допустим 'dddddd' ? То есть как сделать чтоб вот так можно было:
for i := 1 to Length(s) do begin
s1[2 * i - 1] :=s[i];
s1[2 * i] := 'dddddd';
end;

?


Den   (2012-04-09 07:10:00) [8]

О вспомнил про ветку, заглянул. Спасибо всем кто ответил!


Sha   (2012-04-08 18:25:00) [9]

> sniknik ©   (08.04.12 17:56) [13]
> а так?

так быстрее тоже не будет,
1. т.к. по массиву пробегаемся 2 раза
2. т.к. индекс элемента хранится в ОП, а не в регистре

004529B2 8A4C13FF         mov cl,[ebx+edx-$01]
004529B6 8B3424           mov esi,[esp]         <-- грузим индекс из ОП
004529B9 880E             mov [esi],cl             <-- используем
004529BB 83042402         add dword ptr [esp],$02  <-- наращиваем индекс в ОП

> sniknik ©   (08.04.12 18:00) [14]
> в общем, почему какие то "извращения"...

тайна сия великая есть, настоящие герои ходят Дорогой непрямой:
http://guildalfa.ru/alsha/node/10


sniknik   (2012-04-08 18:00:00) [10]

в общем, почему какие то "извращения" с мутными приведением типва к интеджеру, дают лучший код чем явные индексации в массиве/указатели... ведь по смыслу делают то же самое.


sniknik   (2012-04-08 17:56:00) [11]

а так?
 function Split2(const s: AnsiString): AnsiString;
 var
   p: PChar;
   i: integer;
 begin;
   result:= StringOfChar(',', Length(s)*2-1);
   p:= @result[1];
   for i:= 1 to Length(s) do begin
     p^:= s[i];
     Inc(p, 2);
   end;
 end;


Sha   (2012-04-08 17:42:00) [12]

> sniknik ©   (08.04.12 16:33) [10]
> по количеству ассемблерных операций?

нет, по качеству:

     p[0]:= s[i];
004529B2 8A4C13FF         mov cl,[ebx+edx-$01]
004529B6 8B2F             mov ebp,[edi]         <-- это плохой, негодный оператор )
004529B8 884D00           mov [ebp+$00],cl
     p[1]:= ',';
004529BB 8B0F             mov ecx,[edi]         <-- это тоже плохой, негодный оператор )
004529BD C641012C         mov byte ptr [ecx+$01],$2c


Sha   (2012-04-08 17:27:00) [13]

Конечно, [6] - просто демонстрация идеи.
Если говорить об эстетике, то ее можно переписать, например, так

type
 PData= ^TData;
 TData= packed record
   ch: AnsiChar;
   comma: AnsiChar;
   end;
 PDataArray= ^TDataArray;
 TDataArray= array[0..0] of TData;

function Split(const s: AnsiString): AnsiString;
var
 p: PDataArray;
 i: integer;
begin;
 i:=Length(s);
 SetString(Result, nil, 2*i);
 integer(p):=integer(Result); //IA-32 only
 while i>0 do begin;
   dec(i);
   p[i].ch:=s[i+1];
   p[i].comma:=',';
   end;
 end;


При этом и те красота,
и длина цикла будет на 6 байтов меньше, чем [8],
и работать, наверно, быстрее будет )


sniknik   (2012-04-08 16:33:00) [14]

> 1. ответ, как всегда, можно посмотреть в CPU window
по количеству ассемблерных операций? у тебя в первом "блоке" присвоении 4, у меня 3, во втором у тебя одна у меня 2. т.е. то на то. но у меня все регистровые у тебя вторая с переменными (что по моему ИМХО, не очень хорошо для оптимальности)
т.что не увидел я там ответа. а код у меня (опять ИМХО) понятнее/короче.

> 2. не, ну я бы еще оптимальнее запутал ) а потом еще раз )
это я бы тоже по другому написал... чисто с эстетической точки зрения.


Sha   (2012-04-08 15:52:00) [15]

> sniknik ©   (08.04.12 15:32) [8]
> а это точно "Микрооптимизация"? а не запутывание кода?

У меня сразу два ответа
1. ответ, как всегда, можно посмотреть в CPU window
2. не, ну я бы еще оптимальнее запутал ) а потом еще раз )


function Split(const s: AnsiString): AnsiString;
var
 t: pWordArray;
 i, ch: integer;
begin;
 i:=Length(s);
 SetString(Result, nil, 2*i);
 integer(t):=integer(Result); //IA-32 only
 while i>0 do begin;
   ch:=Ord(s[i]);
   dec(i);
   ch:=ch or (Ord(AnsiChar(',')) shl 8);
   t[i]:=ch;
   end;
 end;


sniknik   (2012-04-08 15:32:00) [16]

а это точно "Микрооптимизация"? а не запутывание кода?

более понятное (ИМХО), оно чем то отличается?
 function Split(const s: AnsiString): AnsiString;
 var
   i: integer;
   p: PAnsiChar;
 begin;
   SetLength(result, Length(s)*2);
   p:= PAnsiChar(result);
   for i:= 1 to Length(s) do begin
     p[0]:= s[i];
     p[1]:= ',';
     Inc(p, 2);
   end;
   SetLength(result, Length(result)-1);
 end;


MBo   (2012-04-08 13:45:00) [17]

>Sha
так и знал, что ты не утерпишь, если заглянешь ;)


Sha   (2012-04-08 13:26:00) [18]

Микрооптимизация, о которой говорил MBo ©   (08.04.12 07:13) [5]


function Split(const s: AnsiString): AnsiString;
var
 t, i: integer;
begin;
 SetString(Result, nil, 2*Length(s));
 t:=integer(Result); //IA-32
 for i:=0 to Length(s)-1 do begin;
   pchar(t)[0]:=s[i+1];
   pchar(t)[1]:=',';
   inc(t,2);
   end;
 end;

procedure TForm1.Button1Click(Sender: TObject);
begin;
 ShowMessage(Split('abc'));
 end;


MBo   (2012-04-08 07:13:00) [19]

Радикальное ускорение будет, если избавиться от перевыделения пямяти для обеихстрок


Setlength(s1, Length(s) * 2);
for i := 1 to Length(s) do begin
 s1[2 * i - 1] :=s[i];
 s1[2 * i] := 'a';
end;


Кроме того, еще останется возможность микрооптимизации (понадобится нечасто)


Den   (2012-04-08 02:05:00) [20]


> Вот тут давеча на королевстве обсуждали:
> http://www.delphikingdom.com/asp/answer.asp?IDAnswer=80799

Понял, короче быстро не получиться, придется таки разбирать че там к чему. Спасибо.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо