On Monday, 3 November 2014 at 22:33:25 UTC, Steven Schveighoffer wrote:
On 11/3/14 4:40 PM, Walter Bright wrote:
On 11/3/2014 8:09 AM, Steven Schveighoffer wrote:
It is a huge difference to say EVERYONE who implements toString will
take any
templated type that purports to be an output range, vs giving one case
to handle.

All an output range is is a type with a 'put' method. That's it. You're
making it out to be far more complex than it is.


Directly from the docs: (http://dlang.org/phobos/std_range.html#isOutputRange)

void myprint(in char[] s) { }
static assert(isOutputRange!(typeof(&myprint), char));

No 'put' in sight, except as a substring of isOutputRange.

I don't think you realize what a beast supporting all output ranges is, or using them (hint: calling r.put for a generic output range is an ERROR).

-Steve

In many cases templates are good because they provide the a way for the programmer to use a library optimized for their particular application. This is the case for the toString function. An argument can be made that using templates is dangerous because if they are used incorrectly, the number of template instantiates can blow up. But this can always be solved by the programmer by changing all their template calls to use the same template parameters. This allows the template solution to simultaneously support a sink that represents a real function, or a delegate, or whatever the application needs.

I understand that people like having a binary library that instantiates it's own functions that have a static interface and I think there's value to that. But most of the value is in dynamic libraries that the compiler cannot optimize. When the compiler can optimize, let it:)

I updated my test code to use a templated sink, here the link:

http://marler.info/dtostring.d


   Method 1: ReturnString
             string toString();
   Method 2: SinkDelegate
             void toString(void delegate(const(char)[]) sink);
   Method 3: SinkTemplate
void toString(T)(T sink) if(isOutputRange!(T,const(char)[]));
   Method 4: SinkDelegateWithStaticHelperBuffer
struct SinkStatic { char[64] buffer; void delegate(const(char)[]) sink; }
             void toString(ref SinkStatic sink);
   Method 5: SinkDelegateWithDynamicHelperBuffer
struct SinkDynamic { char[] buffer; void delegate(const(char)[]) sink; }
             void toString(ref SinkDynamic sink);
             void toString(SinkDynamic sink);


(DMD Compiler on x86) "dmd dtostring.d"
RuntimeString run 1 (loopcount 10000000)
  Method 1     : 76 ms
  Method 2     : 153 ms
  Method 3     : 146 ms
  Method 4     : 157 ms
  Method 5ref  : 165 ms
  Method 5noref: 172 ms
StringWithPrefix run 1 (loopcount 1000000)
  Method 1     : 149 ms
  Method 2     : 22 ms
  Method 3     : 21 ms
  Method 4     : 80 ms
  Method 5ref  : 81 ms
  Method 5noref: 82 ms
ArrayOfStrings run 1 (loopcount 1000000)
  Method 1     : 1 sec
  Method 2     : 81 ms
  Method 3     : 77 ms
  Method 4     : 233 ms
  Method 5ref  : 232 ms
  Method 5noref: 223 ms


(DMD Compiler on x86 with Optimization) "dmd -O dtostring.d"
RuntimeString run 1 (loopcount 10000000)
  Method 1     : 30 ms
  Method 2     : 65 ms
  Method 3     : 55 ms
  Method 4     : 68 ms
  Method 5ref  : 68 ms
  Method 5noref: 67 ms
StringWithPrefix run 1 (loopcount 1000000)
  Method 1     : 158 ms
  Method 2     : 9 ms
  Method 3     : 8 ms
  Method 4     : 63 ms
  Method 5ref  : 64 ms
  Method 5noref: 66 ms
ArrayOfStrings run 1 (loopcount 1000000)
  Method 1     : 1 sec, 292 ms
  Method 2     : 35 ms
  Method 3     : 34 ms
  Method 4     : 193 ms
  Method 5ref  : 198 ms
  Method 5noref: 200 ms

The results aren't suprising. The template out performs the delegate sink. In a very big project one might try to limit the number of instantiations of toString by using a specific toString instance that accepts some type common OutputRange wrapper which would make the template version perform the same as the sink delegate version, but for projects that don't need to worry about that, you will get better performance from more compiler optimization.

Reply via email to