Denis Koroskin wrote:
On Thu, 12 Nov 2009 16:23:22 +0300, Steven Schveighoffer
<[email protected]> wrote:
On Thu, 12 Nov 2009 08:22:26 -0500, Steven Schveighoffer
<[email protected]> wrote:
On Tue, 10 Nov 2009 18:49:54 -0500, Andrei Alexandrescu
<[email protected]> 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'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.
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).
I think that, on the contrary, working with a delegate is less generic.
A delegate is cost-wise much like a class with only one (non-final)
method. Since we're taking that hit already, we may as well define
actual interfaces and classes that have multiple methods. That makes
things more flexible and more efficient.
Andrei