mercredi 4 mai 2016

C# Reflection "strange" benchmarks when concatenating property values to a string

I tried to make some reflection benchmark tests, but mostly I managed to confuse myself. Can please someone explain why both tests pass?

For the first one I was expecting it to fail, but the times I got were:

millisecondsReflection - 4970 ms

milliseconds - 6935 ms

    [Fact]
    public void PropertiesGetterString()
    {
        var bar = new Bar
        {
            Id = 42,
            Number = "42",
        };

        string concat = string.Empty;
        string concatReflection = string.Empty;

        var props = bar.GetType().GetProperties();

        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i = 0; i < 100000; i++)
        {
            concatReflection += props[1].GetValue(bar);
        }

        sw.Stop();

        long millisecondsReflection = sw.ElapsedMilliseconds;

        sw.Reset();

        sw.Start();

        for (int i = 0; i < 100000; i++)
        {
            concat += bar.Number;
        }

        sw.Stop();

        long milliseconds = sw.ElapsedMilliseconds;

        millisecondsReflection.Should().BeLessOrEqualTo(milliseconds);
    }

I figured it is something to do with the string concatenation or type conversion, so I changed it to a list append, and got the expected results, i.e. the reflection was slower.

    [Fact]
    public void PropertiesGetterArray()
    {
        var bar = new Bar
        {
            Id = 42,
            Number = "42",
        };

        List<object> concat = new List<object>();
        List<object> concatReflection = new List<object>();

        var props = bar.GetType().GetProperties();

        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i = 0; i < 1000000; i++)
        {
            concatReflection.Add(props[1].GetValue(bar));
        }

        sw.Stop();

        long millisecondsReflection = sw.ElapsedMilliseconds;

        sw.Reset();
        sw.Start();

        for (int i = 0; i < 1000000; i++)
        {
            concat.Add(bar.Number);
        }

        sw.Stop();

        long milliseconds = sw.ElapsedMilliseconds;

        millisecondsReflection.Should().BeGreaterOrEqualTo(milliseconds);
    }

Here the results were:

millisecondsReflection - 184 ms

milliseconds - 11 ms

My question is what I am missing out here?





Aucun commentaire:

Enregistrer un commentaire