umco / umbraco-ditto

Ditto - the friendly view-model mapper for Umbraco
http://our.umbraco.org/projects/developer-tools/ditto
MIT License
79 stars 33 forks source link

Fast property accessors #159

Closed JimBobSquarePants closed 8 years ago

JimBobSquarePants commented 8 years ago

Add compiled cached PropertyInfo accessors and benchmarking code.

This more than doubles the speed on my machine. Hopefully it should do the same on everyone else's. I'd love to see if somehow we could use the performance of dynamic but as far as I'm aware there's no way to get or set the properties without knowing the name at compile time.

:horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing: :horse_racing:

// * Summary *

BenchmarkDotNet=v0.9.4.0
OS=Microsoft Windows NT 6.2.9200.0
Processor=AMD A6-3410MX APU with Radeon(tm) HD Graphics, ProcessorCount=4
Frequency=14318180 ticks, Resolution=69.8413 ns, Timer=HPET
HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
JitModules=clrjit-v4.6.1073.0

                     Method |        Median |     StdDev | Scaled |
--------------------------- |-------------- |----------- |------- |
               1. Static C# |     6.6731 ns |  0.0695 ns |   1.00 |
              2. Dynamic C# |    83.2365 ns |  0.4543 ns |  12.47 |
            3. PropertyInfo | 1,080.9561 ns | 37.0885 ns | 161.99 |
      4. PropertyDescriptor | 2,339.9117 ns | 81.9432 ns | 350.65 |
 5. PropertyInfoInvocations |   410.3465 ns |  3.9585 ns |  61.49 | #Whoop!

// ***** BenchmarkRunner: End *****

1. Static C#: 6.67 ns
2. Dynamic C#: 83.24 ns
3. PropertyInfo: 1,080.96 ns
4. PropertyDescriptor: 2,339.91 ns
5. PropertyInfoInvocations: 410.35 ns
leekelleher commented 8 years ago

@JimBobSquarePants Whoah! :grinning::100:

I've just got back from a holiday, I'll review & merge in asap :+1:

JimBobSquarePants commented 8 years ago

Excellent! I'd like to see if I can squeeze a little more perf (test Concurrent dictionary vs HashTable etc) but I don't think we can get more out of the accessors themselves without using something like FastMember or rolling our own IL code which is hard work.

leekelleher commented 8 years ago

Tried taking a look at it this evening, but hit this issue with BenchmarkDotNet dependencies:

https://github.com/PerfDotNet/BenchmarkDotNet/issues/132

My laptop only has VS2015 installed, so no MSBuild 12 on there (yet). I'll take a look at finding a happy medium, (or I'll install MSBuild 12 :wink:)

leekelleher commented 8 years ago

Quick update: I opted to install MSBuild 12, as I'm an edge-case (e.g. building against .NET 4.5 with only VS2015 tooling). If in future we decide to go .NET 4.6.x, then we can revisit the required tooling.

I'll update the installation/set-up docs in this branch (with download links for MSBuild 12).

leekelleher commented 8 years ago

I'm happy to merge this in! :smiley: Great job @JimBobSquarePants!

@mattbrailsford Did you want to review or feedback before we merge?

mattbrailsford commented 8 years ago

If you are happy, I'm happy 😀

leekelleher commented 8 years ago

Make it so