Testing the new Insert and Delete XE7 that work with arrays (see http://blog.marcocantu.com/blog/2014_september_dynamic_arrays_delphixe7.html)
Testing the new Insert and Delete XE7 that work with arrays (see http://blog.marcocantu.com/blog/2014_september_dynamic_arrays_delphixe7.html)
Wow, they are great. Not only they eliminate the need of that typical loop codes we all have to add and remove items in arrays.
Speed is fantastic, for example 3 times faster for arrays with 1000 items, ( unless the Move function is already used to shift the array memory).
There's one case traditional loops are faster though, when items are of type string or records with string fields (or any managed type I guess).
http://blog.marcocantu.com/blog/2014_september_dynamic_arrays_delphixe7.html
Wow, they are great. Not only they eliminate the need of that typical loop codes we all have to add and remove items in arrays.
Speed is fantastic, for example 3 times faster for arrays with 1000 items, ( unless the Move function is already used to shift the array memory).
There's one case traditional loops are faster though, when items are of type string or records with string fields (or any managed type I guess).
http://blog.marcocantu.com/blog/2014_september_dynamic_arrays_delphixe7.html
The code I used to benchmark:
ReplyDeleteuses
System.Diagnostics;
type
TFoo=record
//Text : String;
Num : Integer;
Float : Single;
end;
TFoos=Array of TFoo;
procedure MyInsert(var Data:TFoos; const AIndex:Integer; const AItem:TFoo);
var L, t: Integer;
begin
L:=Length(Data);
SetLength(Data,L+1);
for t := L downto AIndex+1 do
Data[t]:=Data[t-1];
Data[AIndex]:=AItem;
end;
procedure MyDelete(var Data:TFoos; const AIndex:Integer);
var L, t: Integer;
begin
L:=Length(Data)-1;
for t := AIndex to L-1 do
Data[t]:=Data[t+1];
SetLength(Data,L);
end;
procedure TForm13.Button1Click(Sender: TObject);
procedure Test(Count:Integer);
var
S : TStopwatch;
procedure AddResult(const Prefix:String);
begin
Memo1.Lines.Add(Prefix+' '+Count.ToString+' items: '+S.ElapsedMilliseconds.ToString+' milliseconds');
Application.ProcessMessages;
end;
const
TestTimes=100;
var times,
t : Integer;
Data : TFoos;
Dummy : TFoo;
begin
//Dummy.Text:='abc';
Dummy.Num:=1234;
Dummy.Float:=567.89;
SetLength(Data,Count*2);
S:=TStopwatch.StartNew;
for times := 1 to TestTimes do
begin
for t := 0 to Count-1 do
MyInsert(Data,t,Dummy);
for t := 0 to Count-1 do
MyDelete(Data,t);
end;
S.Stop;
AddResult('OLD way');
SetLength(Data,Count*2);
S:=TStopwatch.StartNew;
for times := 1 to TestTimes do
begin
for t := 0 to Count-1 do
Insert(Dummy,Data,t);
for t := 0 to Count-1 do
Delete(Data,t,1);
end;
S.Stop;
AddResult('NEW way');
end;
begin
Test(10);
Test(100);
Test(1000);
end;
Nice you like this feature. I thing it is a great addition. we were considering adding Pos() as well, but it is a bit tricky... maybe in the future.
ReplyDeleteDavid Berneda Nice, but to satisfy the curiosity of those of us not on XE7, what did the performance results look like? I mean, in some detail....
ReplyDeleteMarco Cantù The more sugar the better ! Also a helper class for array ie: foo.delete(123) could bridge to a future common root
ReplyDeleteBill Meyer The above code on a 3 year old i5 notebook shows:
ReplyDeleteOLD way 10 items: 0 milliseconds
NEW way 10 items: 0 milliseconds
OLD way 100 items: 10 milliseconds
NEW way 100 items: 6 milliseconds
OLD way 1000 items: 999 milliseconds
NEW way 1000 items: 509 millisecond
About half the time. I guess the savings would be proportional independant of cpu speed.
David Berneda Thanks!
ReplyDeleteMarco Cantù I know it's nice, that's why I filed a feature request for them some 10 years ago :P
ReplyDelete