From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,4e04f7888d82ca71,start X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!news1.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: "Alex R. Mosteo" Newsgroups: comp.lang.ada Subject: Efficiency of returning big objects Date: Mon, 25 Sep 2006 14:14:44 +0200 Message-ID: <4npvh0FbgbuhU1@individual.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7Bit X-Trace: individual.net /W9+i70LEsro167iX9g8YAY6WaUS3GMjQ0u+z9yVKwPKudmUs= User-Agent: KNode/0.10.4 Xref: g2news2.google.com comp.lang.ada:6721 Date: 2006-09-25T14:14:44+02:00 List-Id: Hello, I had a concern over the efficiency of returning big (tagged) types, since I like to store them in indefinite collections (a la Object'Class) instead of storing pointers to them. It is said that, as tagged types are passed by reference, they are always efficiently passed around. However, when you are /returning/ and not calling, I had my doubts, so I have made this simple testcase (see at bottom). Here is a typical execution: $ ./ref Direct access: 341312 Indirect access: 76992 Pass constant: 336507 Pass value: 72573 It has been compiled with just gnatmake -O3. It reveals that a copy is created in the stack for returning every time. I was hoping that, as long as the type were used as a constant, a reference would be returned and passed around. This would be very interesting in collections, since we could do, for example: Some_Map.Element (Key).Method_Or_Member without efficiency penalties. Now, in C++ I would force this behavior explicitly returning references (I guess this is the usual practice, but I'm not sure). In Ada, I have no idea how to match this efficient behavior. So, what do you think? Is there some error in my reasoning or testbed? Is this a particular shortcoming of this compiler (gnat gpl 2006), or I'm overlooking something that makes this very non-trivial to implement? Thanks in advance for your comments, A. Mosteo. -------8<--------- with Ada.Calendar; use Ada.Calendar; with Ada.Text_Io; use Ada.Text_Io; procedure Ref is type Big_Thing is array (1 .. 64_000) of Character; type T is tagged record Dummy : Big_Thing := (others => 'c'); X : Integer := 0; end record; procedure Check (Y : T) is begin if Y.X /= 0 then raise Constraint_Error; end if; end Check; Borg : T; function Create return T is begin return Borg; end Create; Start : Time; Iters : Natural; begin -- Direct access, cheap. Iters := 0; Start := Clock; while Clock - Start < 1.0 loop if Borg.X /= 0 then raise Constraint_Error; end if; Iters := Iters + 1; end loop; Put_line ("Direct access:" & Natural'Image (Iters)); -- Indirect access. Iters := 0; Start := Clock; while Clock - Start < 1.0 loop if Create.X /= 0 then raise Constraint_Error; end if; Iters := Iters + 1; end loop; Put_line ("Indirect access:" & Natural'Image (Iters)); -- Pass by reference, cheap. Iters := 0; Start := Clock; while Clock - Start < 1.0 loop Check (Borg); Iters := Iters + 1; end loop; Put_line ("Pass constant:" & Natural'Image (Iters)); -- Pass - how? Iters := 0; Start := Clock; while Clock - Start < 1.0 loop Check (Create); Iters := Iters + 1; end loop; Put_line ("Pass value:" & Natural'Image (Iters)); end Ref; -------8<--------------------------------