danielwertheim

danielwertheim


notes from a passionate developer

Developer that lives by the mantra "code is meant to be shared".

Share


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

New interesting results for dynamic result extraction of a generic Task in C#

Daniel WertheimDaniel Wertheim

This is an update to my previous post "Comparing dynamic result extraction of a generic Task in C#" in which I got a comment to extend the benchmarks with more data types as the dynamic call site caching would get affected by it. Yes our course. Good point. So lets have a look.

UPDATED 2017-03-04: There was an issue in timing the Lambda cache. Code on GitHub has been corrected and the results in the post updated.

The test code is of course again BenchmarkDotNet. You can have a look at the benchmark scenarios on GitHub. I'll only show you some pieces in this post.

In this case, I'm just as before, comparing:

but this time, for each case above, it's done for more data types to Task<T>. So each type gets one ICase instance.

public interface ICase  
{
    void ExtractUsingReflection();
    void ExtractUsingReflectionWithSameProp();
    void ExtractUsingReflectionWithCache();
    void ExtractUsingIlWithSameGetter();
    void ExtractUsingIlWithCache();
    void ExtractUsingLambdaWithSameGetter();
    void ExtractUsingLambdaWithCache();
    void ExtractUsingDynamic();
}

The benchmarks are now for the following cases:

_cases = new List<ICase>  
{
    new Case<Thing>(new Thing("Some value")),
    new Case<string>("Some other value"),
    new Case<int>(42),
    new Case<decimal>(3.14M),
    new Case<bool>(true),
    new Case<DateTime>(DateTime.Now),
    new Case<List<int>>(new List<int> { 1, 2, 3, 4, 5 }),
    new Case<string[]>(new []{ ".Net", "C#", "Benchmark" })
};

Results

Dynamic is still the fastest but the more items that are passed the tinier is the difference.

BenchmarkDotNet=v0.10.1, OS=Microsoft Windows NT 6.2.9200.0  
Processor=Intel(R) Core(TM) i7-4790K CPU 4.00GHz, ProcessorCount=8  
Frequency=3906248 Hz, Resolution=256.0001 ns, Timer=TSC  
  [Host]     : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1586.0
  DefaultJob : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1586.0
                             Method | Count |            Mean |      StdDev |
----------------------------------- |------ |---------------- |------------ |
                    UsingReflection |     1 |   1,547.2108 ns |   1.0584 ns |
        UsingReflectionWithSameProp |     1 |   1,097.0576 ns |   1.3476 ns |
           UsingReflectionWithCache |     1 |   1,274.5588 ns |   1.8150 ns |
              UsingIlWithSameGetter |     1 |     141.2156 ns |   0.6715 ns |
                   UsingIlWithCache |     1 |     323.4523 ns |   1.2865 ns |
 UsingCompiledLambdasWithSameGetter |     1 |     139.3107 ns |   0.1356 ns |
      UsingCompiledLambdasWithCache |     1 |     321.0852 ns |   0.6173 ns |
                       UsingDynamic |     1 |     289.7966 ns |   0.2968 ns |
                    UsingReflection |    10 |  15,590.5413 ns |  15.8068 ns |
        UsingReflectionWithSameProp |    10 |  10,851.8057 ns |  12.5348 ns |
           UsingReflectionWithCache |    10 |  12,736.8844 ns |  18.9407 ns |
              UsingIlWithSameGetter |    10 |   1,405.4752 ns |   1.6704 ns |
                   UsingIlWithCache |    10 |   3,228.6196 ns |   5.5269 ns |
 UsingCompiledLambdasWithSameGetter |    10 |   1,395.5572 ns |   0.9862 ns |
      UsingCompiledLambdasWithCache |    10 |   3,236.3327 ns |   3.4060 ns |
                       UsingDynamic |    10 |   2,930.4902 ns |   2.2173 ns |
                    UsingReflection |   100 | 154,451.5112 ns |  80.5138 ns |
        UsingReflectionWithSameProp |   100 | 108,825.8807 ns |  57.5746 ns |
           UsingReflectionWithCache |   100 | 126,726.6482 ns | 153.8243 ns |
              UsingIlWithSameGetter |   100 |  14,033.8887 ns |  11.2025 ns |
                   UsingIlWithCache |   100 |  31,935.7428 ns |  35.7639 ns |
 UsingCompiledLambdasWithSameGetter |   100 |  13,896.3436 ns |  10.9140 ns |
      UsingCompiledLambdasWithCache |   100 |  32,176.6193 ns |  21.9242 ns |
                       UsingDynamic |   100 |  28,818.3686 ns |  35.4783 ns |

The end.

//Daniel

Developer that lives by the mantra "code is meant to be shared".

Comments