Exemplo n.º 1
0
        public void Should_set_properties_faster_than_reflection()
        {
            var iterations = 10000;
            var type       = new TypeCache().GetTypeDescriptor(typeof(HydratedObject));
            var values     = new List <string, object>
            {
                { "value0", "farker" },
                { "value1", "fark" },
                { "value2", "valueA" },
                { "value2", "valueB" }
            }.ToLookup();
            Func <PropertyDescriptor, object[], MapResult> map = (p, o) => MapResult.WasMapped(o);

            var nativeElapsed     = new List <long>();
            var reflectionElapsed = new List <long>();
            var expressionElapsed = new List <long>();

            Action run = () =>
            {
                expressionElapsed.Add(type.ElapsedTicks(x => x.CreateAndBind(values, map)));
                reflectionElapsed.Add(values.ElapsedTicks(x =>
                {
                    values.ForEach(v =>
                    {
                        var instance = Activator.CreateInstance(typeof(HydratedObject));
                        var property = type.Properties.FirstOrDefault(p => p.Name
                                                                      .Equals(v.Key, StringComparison.OrdinalIgnoreCase));
                        if (property != null)
                        {
                            var result = map(property, v.ToArray());
                            if (result.Mapped)
                            {
                                property.PropertyInfo.SetValue(instance, result.Value);
                            }
                        }
                    });
                }));
                nativeElapsed.Add(values.ElapsedTicks(x =>
                {
                    var instance = new HydratedObject();
                    foreach (var value in values)
                    {
                        if (value.Key.Equals("value1", StringComparison.OrdinalIgnoreCase))
                        {
                            var result = map(null, value.ToArray());
                            if (result.Mapped)
                            {
                                instance.Value1 = (object[])result.Value;
                            }
                        }
                        else if (value.Key.Equals("value2", StringComparison.OrdinalIgnoreCase))
                        {
                            var result = map(null, value.ToArray());
                            if (result.Mapped)
                            {
                                instance.Value2 = (object[])result.Value;
                            }
                        }
                    }
                }));
            };

            100.Times(run); // Warmup

            nativeElapsed.Clear();
            reflectionElapsed.Clear();
            expressionElapsed.Clear();

            iterations.Times(run);

            Console.WriteLine($"Native:              {nativeElapsed.Average()}");
            Console.WriteLine($"Compiled expression: {expressionElapsed.Average()}");
            Console.WriteLine($"Reflection:          {reflectionElapsed.Average()}");
        }