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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,c52c30d32b866eae X-Google-Attributes: gidfac41,public X-Google-Thread: 103376,2ea02452876a15e1 X-Google-Attributes: gid103376,public X-Google-Thread: 1108a1,c52c30d32b866eae X-Google-Attributes: gid1108a1,public From: kanze@gabi-soft.fr (J. Kanze) Subject: Re: Real OO Date: 1996/04/10 Message-ID: #1/1 X-Deja-AN: 146702282 references: <65lDeVZF3RB@herold.franken.de> followup-to: comp.lang.eiffel,comp.lang.ada,comp.object organization: GABI Software, Sarl. newsgroups: comp.lang.eiffel,comp.lang.ada,comp.object Date: 1996-04-10T00:00:00+00:00 List-Id: In article rmartin@oma.com (Robert C. Martin) writes: |> I recently conducted just such an experiment in C++. |> class F |> { |> public: |> void nv(); |> virtual void v(); |> }; |> void F::nv() {} |> void F::v() {} |> F f; |> F& fr=f; |> fr.nv(); |> fr.v(); |> Executing this on a 486-33 laptop I found that the call to nv took |> 998ns and the call to v took 1142ns, or 144 extra nanoseconds. The |> compiler was Borland 4.1. |> On the other hand, I benchmarked this same test on a popular compiler |> for the 68000. The machine was proprietary, and so I cannot give you |> the exact environment. However the timings were telling. nv required |> about 2000ns, and v required 4000ns. Nearly a doubling. |> It seems clear that the performance delta between virtual and |> non-virtual functions can vary significantly between compilers. At least for empty functions called from a tight loop:-). Independantly of that actual call/return sequence, a function call involves two things: finding the address of the function, and setting up the local stack frame. The only difference between virtual and non-virtual functions will be in the first, finding the address. If the function is empty, or simply if it has no local variables or arguments, some compilers will optimize by not building the local stack frame. Since I suspect that on an 80x86 architecture, building the local stack frame costs more than the actual call, the percentage gain relative to the actual call will be much more significant if the compiler does this optimization. (From the Borland figures, I suspect that it doesn't.) On the other hand, the actual function address is in fact a loop invariant; a compiler could potentially hoist it out of the loop completely. In this case, we might actually measure that virtual functions were faster. Even holding `fr' in a register in the loop will make a noticeable gain (and will reduce the difference between virtual and non-virtual functions). I would suggest that neither of these conditions are typical in real programs. Depending on what the compiler optimizes, they may be slanted for or against virtual functions, but either way, they do not exterpolate easily. The only practical solution is to write your program cleanly, and profile if there is a performance problem. If profiling shows that an inordinate amount of time is spent in a small loop which does nothing but call a trivial virtual function, and in fact, the function involved is always the same, I would consider making the function non-virtual. Otherwise, I wouldn't bother. (I would probably also look at the generated assembler. If the compiler is already hoisting the calcule of the virtual address out of the loop, there's not much to be gained by making the function non-virtual.) -- James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France Conseils en informatique industrielle -- -- Beratung in industrieller Datenverarbeitung