Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Вниззаранее задать размер строки 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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.073 c