Fasterflect vs HyperDescriptor vs FastMember vs Reflection

The oth­er day I had a small task to inspect return val­ues of meth­ods and if the fol­low­ing prop­er­ty exists then set it to emp­ty array.

        pub­lic long[] Achieve­ments { get; set; }

This need­ed to hap­pen once on every web request, and I decid­ed to imple­ment it as a Post­Sharp attribute. WHY I need­ed to do this is anoth­er inter­est­ing dis­cus­sion, but broad­ly speak­ing boils down to assump­tions baked into base class’s con­trol flows  no longer holds true but is inflex­i­ble to change.

A major refac­tor­ing is in order, but giv­en we have a dead­line to meet, let’s take a tech­ni­cal debt and make sure it’s in the back­log so we know to come back to it.

 

So I went about find­ing a more effi­cient way of doing this than hand-writ­ing some reflec­tion code.

There’s Jon Skeet’s famous reflec­tion post but to make it work across all types and incor­po­rat­ing IL emit is more com­plex than this task war­rants.

side­bar : if you’re still inter­est­ed in see­ing how Jon’s tech­nique can be applied, check out FSharpx.Reflection to see how it’s used to make reflec­tion over F# types fast.

Then there’s Marc Gravell’s Hyper­De­scrip­tor although the Nuget  pack­age itself was authored by some­one else. Plus Marc’s fol­low-up to Hyper­De­scrip­torFast­Mem­ber.

I also came across a pack­age called Faster­flect which I wasn’t aware of before, from its project page the API looks pret­ty clean.

 

Test 1 — 1M instances of MyTypeA

Sup­pose I have a type, with the Achieve­ments prop­er­ty that I want to set to emp­ty when­ev­er I see it returned by a method.

image

To do this with reflec­tion is pret­ty straight for­ward:

image

With Faster­flect, this becomes:

image

I do like this API, it’s very intu­itive.

And here’s how it looks with Hyper­De­scrip­tor and Fast­Mem­ber:

image

Now let’s run this across 1M instance of MyTy­peA and see how they do. Both Faster­flect and Fast­Mem­ber did real­ly well although Hyper­De­scrip­tor was 3x slow­er than basic reflec­tion!

image

 

Test 2 — 1M instances of MyTypeA and MyTypeB

Ok, but since this code has to work across many types, so we have to expect both

  • types that has this prop­er­ty, and
  • types that don’t

To sim­u­late that, let’s intro­duce anoth­er type into the test.

image

Instead of work­ing with an array of MyTy­peA, now we have a mixed array of both MyTy­peA and MyTypeB for our test.

image

and the result over 1M objects makes for inter­est­ing read­ings:

image

some obser­va­tions from this set of results:

  • we need to invoke the set­ter on only half the objects, so reflec­tion is faster (almost halved) than before, makes sense;
  • both Fast­Mem­ber and Hyper­De­scrip­tor are faster due to the same rea­son as above;
  • hav­ing less work to do had much small­er impact on Fast­Mem­ber sug­gests some caching around the call site (and indeed it does);
  • WTF is going on with Faster­flect!

 

Conclusions

The morale of this sto­ry is that – always ver­i­fy claims against your par­tic­u­lar use case.

Anoth­er per­fect exam­ple of this is Kyle Kingsbury’s work with Jepsen. Where he uses a gen­er­a­tive test­ing approach to ver­i­fy whether NoSQL data­bas­es actu­al­ly pro­vide the con­sis­ten­cy mod­el that they claims to offer. His find­ings are very inter­est­ing to read, and in many cas­es pret­ty wor­ry­ing

Oh, and stick with Fast­Mem­ber or reflec­tion 

 

Links