On Thu, 12 Nov 2009 08:56:06 -0500, Denis Koroskin <2kor...@gmail.com>
wrote:
On Thu, 12 Nov 2009 16:23:22 +0300, Steven Schveighoffer
<schvei...@yahoo.com> wrote:
On Thu, 12 Nov 2009 08:22:26 -0500, Steven Schveighoffer
<schvei...@yahoo.com> wrote:
On Tue, 10 Nov 2009 18:49:54 -0500, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
I think the best option for toString is to take an output range and
write to it. (The sink is a simplified range.)
Bad idea...
A range only makes sense as a struct, not an interface/object. I'll
tell you why: performance.
Ranges are special in two respects:
1. They are foreachable. I think everyone agrees that calling 2
interface functions per loop iteration is much lower performing than
using opApply, which calls one delegate function per loop. My
recommendation -- use opApply when dealing with polymorphism. I don't
think there's a way around this.
Oops, I meant 3 virtual functions -- front, popNext, and empty.
-Steve
Output range has only one method: put.
I was referring to range's ability to interact with foreach. An output
range wouldn't qualify as a foreachable entity anyways (and rightfully
so). Just covering all the bases.
I'm not sure, but I don't think there is a performance difference
between calling a virtual function through an interface and invoking a
delegate.
Yes, there is:
A delegate is equivalent to a struct member function call. (load data
pointer (i.e. this), push args, call function)
A virtual function uses a vtable to look up the function address, and then
is equivalent to a struct member call.
An interface function call is equivalent to a virtual call with the added
penalty that you might have to adjust the 'this' pointer before calling.
But I agree passing a delegate is more generic. You can substitute an
output range with a delegate (obj.toString(&range.put, fmt)) without any
performance hit, but not vice versa (obj.toString(new
DelegateWrapRange(&myput), fmt) implies an additional allocation and
additional indirection per range.put call).
You can use scope classes to avoid the allocation, but you can't get
around the virtual/interface call penalty.
But even if a range is a struct, it's simply a different form of delegate,
one in which you undoubtedly call only one member function. Might as well
use a delegate to allow the most usefulness.
-Steve