D perfomance

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Sat Apr 25 10:34:44 UTC 2020


On Saturday, 25 April 2020 at 10:15:33 UTC, Walter Bright wrote:
> On 4/24/2020 12:27 PM, Arine wrote:
>> There most definitely is a difference and the assembly 
>> generated with rust is better.
> D's @live functions can indeed do such optimizations, though I 
> haven't got around to implementing them in DMD's optimizer. 
> There's nothing particularly difficult about it.

In any case, I seriously doubt those kinds of optimization have 
anything to do with the web framework performance differences.

My experience of writing number-crunching stuff in D and Rust is 
that Rust seems to have a small but consistent performance edge 
that could quite possibly be down the kind of optimizations that 
Arine mentions (that's speculation: I haven't verified).  
However, it's small differences, not order-of-magnitude stuff.

I suppose that in a more complicated app there could be some 
multiplicative impact, but where high-throughput web frameworks 
are concerned I'm pretty sure that the memory allocation and 
reuse strategy is going to be what makes 99% of the difference.

There may also be a bit of an impact from the choice of futures 
vs. fibers for managing asynchronous tasks (there's a context 
switching cost for fibers), but I would expect that to only make 
a difference at the extreme upper end of performance, once other 
design factors have been addressed.

BTW, on the memory allocation front, Mathias Lang has pointed out 
that there is quite a nasty impact from `assumeSafeAppend`.  
Imagine that your request processing looks something like this:

     // extract array instance from reusable pool,
     // and set its length to zero so that you can
     // write into it from the start
     x = buffer_pool.get();
     x.length = 0;
     assumeSafeAppend(x);   // a cost each time you do this

     // now append stuff into x to
     // create your response

     // now publish your response

     // with the response published, clean
     // up by recycling the buffer back into
     // the pool
     buffer_pool.recycle(x);

This is the kind of pattern that Sociomantic used a lot.  In D1 
it was easy because there was no array stomping prevention -- you 
could just set length == 0 and start appending.  But having to 
call `assumeSafeAppend` each time does carry a performance cost.

IIRC Mathias has suggested that it should be possible to tag 
arrays as intended for this kind of re-use, so that stomping 
prevention will never trigger, and you don't have to 
`assumeSafeAppend` each time you reduce the length.


More information about the Digitalmars-d mailing list