comp.lang.ada
 help / color / mirror / Atom feed
* Performance of element access in Vector
@ 2009-01-18 21:42 Maciej Sobczak
  2009-01-19  0:03 ` george.priv
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Maciej Sobczak @ 2009-01-18 21:42 UTC (permalink / raw)


In a nearby thread I have asked about the performance of
Update_Element in Vector.
The question was related to using the same interface in smart pointers
(and other containers/handlers).

So I wrote a test:

with Ada.Calendar.Formatting;
with Ada.Containers.Vectors;
with Ada.Text_IO;

procedure A is

   package Int_Vectors is new Ada.Containers.Vectors
     (Index_Type => Positive, Element_Type => Integer);

   V : Int_Vectors.Vector := Int_Vectors.To_Vector(0, 1_000_000);

   procedure Increment (I : in out Integer) is
   begin
      I := I + 1;
   end Increment;

   Iterations : constant := 10_000;

   Start : Ada.Calendar.Time;
   Stop : Ada.Calendar.Time;

   use type Ada.Calendar.Time;

   procedure Test_1 is
   begin
      Start := Ada.Calendar.Clock;

      for J in 1 .. Iterations loop
         for I in V.First_Index .. V.Last_Index loop
            V.Replace_Element (I, V.Element (I) + 1);
         end loop;
      end loop;

      Stop := Ada.Calendar.Clock;
      Ada.Text_IO.Put_Line
        ("direct index             : " &
           Ada.Calendar.Formatting.Image (Stop - Start, True));
   end Test_1;

   procedure Test_2 is
   begin
      Start := Ada.Calendar.Clock;

      for J in 1 .. Iterations loop
         for I in V.First_Index .. V.Last_Index loop
            V.Update_Element (I, Increment'Access);
         end loop;
      end loop;

      Stop := Ada.Calendar.Clock;
      Ada.Text_IO.Put_Line
        ("Update_Element and index : " &
           Ada.Calendar.Formatting.Image (Stop - Start, True));
   end Test_2;

   procedure Test_3 is
      C : Int_Vectors.Cursor;
   begin
      Start := Ada.Calendar.Clock;

      for J in 1 .. Iterations loop
         C := V.First;
         while Int_Vectors.Has_Element (C) loop
            V.Replace_Element (C, Int_Vectors.Element (C) + 1);
            Int_Vectors.Next (C);
         end loop;
      end loop;

      Stop := Ada.Calendar.Clock;
      Ada.Text_IO.Put_Line
        ("direct cursor            : " &
           Ada.Calendar.Formatting.Image (Stop - Start, True));
   end Test_3;

   procedure Test_4 is
      C : Int_Vectors.Cursor;
   begin
      Start := Ada.Calendar.Clock;

      for J in 1 .. Iterations loop
         C := V.First;
         while Int_Vectors.Has_Element (C) loop
            V.Update_Element (C, Increment'Access);
            Int_Vectors.Next (C);
         end loop;
      end loop;

      Stop := Ada.Calendar.Clock;
      Ada.Text_IO.Put_Line
        ("Update_Element and cursor: " &
           Ada.Calendar.Formatting.Image (Stop - Start, True));
   end Test_4;

   procedure Test_5 is

      procedure Increment (C : in Int_Vectors.Cursor) is
      begin
         V.Replace_Element (C, Int_Vectors.Element (C) + 1);
      end Increment;

   begin
      Start := Ada.Calendar.Clock;

      for J in 1 .. Iterations loop
         V.Iterate (Increment'Access);
      end loop;

      Stop := Ada.Calendar.Clock;
      Ada.Text_IO.Put_Line
        ("Iterate                  : " &
           Ada.Calendar.Formatting.Image (Stop - Start, True));
   end Test_5;

begin
   Test_1;
   Test_2;
   Test_3;
   Test_4;
   Test_5;
end A;

Each of the tests increments all vectors elements, using several
element access methods.
Here we go:

~/temp/ada $ gnatmake -O2 -gnatn -gnatN a
gcc -c -O2 -gnatn -gnatN a.adb
gnatbind -x a.ali
gnatlink a.ali
~/temp/ada $ ./a
direct index             : 00:00:23.34
Update_Element and index : 00:02:17.20
direct cursor            : 00:01:03.32
Update_Element and cursor: 00:02:25.82
Iterate                  : 00:01:48.67
~/temp/ada $

The test shows that Update_Element is several time slower than
accessing elements by index. Cursor also adds some overhead.

A possible conclusion is that for small elements (simple numeric
types, etc.) it makes sense to access elements by index, when they are
copied from and into the container. For larger elements the benefit of
accessing element in-place can be greater than the overhead of
Update_Element.

Just to stir the discussion a bit, a straightforward implementation of
the same test in C++ (with the same base compiler and a single -O2
option) runs in 13s with indexed access and in 9.5s with iterators -
both are based on the use of references, which do not exist in Ada.
Not very easy to neglect this difference.

All comments are welcome.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2009-01-23 17:30 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-18 21:42 Performance of element access in Vector Maciej Sobczak
2009-01-19  0:03 ` george.priv
2009-01-19  3:23 ` george.priv
2009-01-19 11:25   ` Georg Bauhaus
2009-01-19 16:32   ` (see below)
2009-01-20  2:17 ` Randy Brukardt
2009-01-20  8:03   ` Maciej Sobczak
2009-01-20  8:26     ` Dmitry A. Kazakov
2009-01-20 22:07       ` george.priv
2009-01-21  8:52         ` Maciej Sobczak
2009-01-21 19:25           ` george.priv
2009-01-22 10:01             ` Georg Bauhaus
2009-01-22 12:43               ` Maciej Sobczak
2009-01-22 13:52               ` george.priv
2009-01-21  8:59         ` Dmitry A. Kazakov
2009-01-21  9:19           ` Maciej Sobczak
2009-01-21 10:19             ` Dmitry A. Kazakov
2009-01-21 13:14               ` Maciej Sobczak
2009-01-21 19:00                 ` Dmitry A. Kazakov
2009-01-21 13:22             ` Georg Bauhaus
2009-01-23 14:56         ` Alex R. Mosteo
2009-01-20 23:01   ` Randy Brukardt
2009-01-21  9:15     ` Maciej Sobczak
2009-01-21 18:08       ` Georg Bauhaus
2009-01-23 14:55         ` Alex R. Mosteo
2009-01-23 17:30           ` Georg Bauhaus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox