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

Вниз

заранее задать размер строки Setlength ?   Найти похожие ветки 

 
Den   (2012-04-08 00:21) [0]

задача: ускорить выполнение кода.
есть 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 перезаписываться в другое место в памяти если ей начать присваивать какие-то значения?


 
Германн ©   (2012-04-08 01:18) [1]


> это обнулит ее length или нет? То есть будет ли s1 перезаписываться
> в другое место в памяти если ей начать присваивать какие-
> то значения?
>

1. Обнулит.
2. Считай что будет. Исключения возможны, но не обязательны.

Задачу озвучь, а не вопрос.


 
Германн ©   (2012-04-08 01:22) [2]

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


 
Den   (2012-04-08 02:03) [3]


> Задачу озвучь, а не вопрос.


Да какая задача постоянно то там то там приходиться обрабатывать кучу строк мысли по поводу того как это ускорить навеяны вот этой статьей, http://www.delphimaster.ru/articles/dyntable/index.html

var
 s: string; //ansistring
 ch: char;
 i, N: integer;
begin
1.  S:= "";
2. for i := 1 to N do
3.    s := s + ch;
...

Первая строка - на самом деле S := nil, довольно просто. А вот третья раскладывается на выделение памяти для новой строки длины (Length(S) + 1) и копирование прежней строки в новую область памяти, после этого S указывает на эту область. И так N раз! На самом деле, в цикле еще идет вызов UniqueString, что тоже не добавляет скорости. И если выделение области памяти сравнительно быстрая операция, то время копирования прежней строки на новое место напрямую зависит от ее длины. Можно показать, что время выполнения строк 2 и 3 пропорционально N^2.


Вот и думаю как ускорить обработку строк, чтоб посмотреть хотябы насколько оно быстрее работать будет.


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


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

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


 
MBo ©   (2012-04-08 07:13) [5]

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


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


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


 
Sha ©   (2012-04-08 13:26) [6]

Микрооптимизация, о которой говорил 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 13:45) [7]

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


 
sniknik ©   (2012-04-08 15:32) [8]

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

более понятное (ИМХО), оно чем то отличается?
 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;


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

> 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 16:33) [10]

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

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


 
Sha ©   (2012-04-08 17:27) [11]

Конечно, [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],
и работать, наверно, быстрее будет )


 
Sha ©   (2012-04-08 17:42) [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


 
sniknik ©   (2012-04-08 17:56) [13]

а так?
 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;


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

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


 
Sha ©   (2012-04-08 18:25) [15]

> 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


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

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


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


> 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 08:32) [18]

Так наверное можно:
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 08:39) [19]

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

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;


 
MBo ©   (2012-04-09 08:46) [20]

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:51) [21]

MBo Спасибо!


 
oldman ©   (2012-04-09 10:25) [22]


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


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


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

Ну я в нее ем:)



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

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

Наверх




Память: 0.53 MB
Время: 0.061 c
2-1328768439
Александр_2012
2012-02-09 10:20
2013.03.22
Ввод шрифтов, формирующих таблицы в кнопки и редакторы


15-1329643520
AV
2012-02-19 13:25
2013.03.22
Посоветуйте что-нибудь, компонент не хочет работать в службе..


15-1333730960
Дмитрий С
2012-04-06 20:49
2013.03.22
Очень сильно тупит delphiXE


15-1340137805
Юрий
2012-06-20 00:30
2013.03.22
С днем рождения ! 20 июня 2012 среда


2-1333845479
SiDimka
2012-04-08 04:37
2013.03.22
Как инициализировать объект?