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

Comments

  1. The code I used to benchmark:


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

    ReplyDelete
  2. 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.

    ReplyDelete
  3. David 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....

    ReplyDelete
  4. Marco Cantù The more sugar the better ! Also a helper class for array ie: foo.delete(123) could bridge to a future common root

    ReplyDelete
  5. Bill Meyer The above code on a 3 year old i5 notebook shows:

    OLD 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.

    ReplyDelete
  6. Marco Cantù I know it's nice, that's why I filed a feature request for them some 10 years ago :P

    ReplyDelete

Post a Comment