www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Moderately interesting: writing efficient serializers in C# (Wire


It's interesting to compare what C# does and what people do in C# 
to promote speed over obviousness of implementation, with what D 
does by default and what's natural to do in D.

A direct comparison isn't trivial -- C# uses runtime reflection 
and D uses primarily compile-time.

Some specific parts that stood out to me:

* Looking up typeinfo
In D, TypeInfo is just an instance of some class that extends 
TypeInfo. When you write `typeof(foo)`, the compiler transforms 
that into a reference to the appropriate TypeInfo instance. On 
.NET, the primitive operation is to get a type handle for the 
type (done at compile time), and at runtime .NET performs a 
lookup based on that type handle.

* Dictionaries are slower than switch statements. Not surprising.

* Passing preallocated buffers. D has that concept baked in at 
this point; it's almost easier to use Appender!string than to 
append to a string. But this was apparently not natural in C#.

* When you are attempting to serialize millions of objects per 
second, virtual call overhead and uninlined functions matter. 
Wire uses code generation to eliminate both of these problems.

* In .NET, it's apparently not fast to create an uninitialized 
object. You can examine the bytecode for a function (including 
constructors) to determine whether a type has any code, which 
might include side effects, in its constructor.

In D, we can inspect the ClassInfo flags:

if ((Foo.classinfo.m_flags & ClassInfo.ClassFlags.hasCtor) == 0) {
   // static if is here just to ensure that this isn't compiled 
for types that
   // don't have a no-args ctor
   static if (is(typeof(new Foo))) {
     obj = new Foo;
     goto initialized;
obj = hackyManualInitialization!Foo;

(As an aside, I think I'm warming up to goto as an alternative to 
setting a flag and checking it later.)
Aug 17 2016