Минутка WTF-5: реально WTF
От: Sinix  
Дата: 23.04.16 15:49
Оценка: 34 (3)
Обещал позабористей, чем это
Автор: Sinix
Дата: 20.04.16
?

Ну вот держите:
        public struct HeavyStruct
        {
            private readonly decimal _a;
            private readonly decimal _b;
            private readonly decimal _c;
            private readonly decimal _d;
            private readonly decimal _e;
            private readonly decimal _f;
            private readonly decimal _g;
            private readonly decimal _h;

            public decimal Test() => _a;
        }

        public struct HeavyStructWrapper
        {
            private readonly HeavyStruct _h;

            public decimal CallTest() => _h.Test();
        }


Чего не так-то?
Чтоб не посылать в ложном направлении: нет, проблема не в отсутствующих Equals/GetHashCode, не влияют.

Поскольку вопрос действительно заковыристый,
  подсказка:
каким образом нужно поменять HeavyStructWrapper2 (код ниже) так, чтобы получить вот такой вот вывод:
                 wrapper1:  1013ms, ips:          98 634 922,27 | Mem:   8,00 kb, GC 0/1/2: 0/0/0 => 100000000
                 wrapper2:   146ms, ips:         683 613 443,94 | Mem:   3,91 kb, GC 0/1/2: 0/0/0 => 100000000

Done.


менять только код в HeavyStructWrapper2, метод CallTest не трогать

Сам код бенчмарка (запускать без отладчика, Ctrl-F5):
using System;
using System.Diagnostics;

namespace Samples
{
    class Program
    {
#pragma warning disable 169
#pragma warning disable 649
        public struct HeavyStruct
        {
            private readonly decimal _a;
            private readonly decimal _b;
            private readonly decimal _c;
            private readonly decimal _d;
            private readonly decimal _e;
            private readonly decimal _f;
            private readonly decimal _g;
            private readonly decimal _h;

            public decimal Test() => _a;
        }

        public struct HeavyStructWrapper
        {
            private readonly HeavyStruct _h;

            public decimal CallTest() => _h.Test();
        }

        public struct HeavyStructWrapper2
        {
            private readonly HeavyStruct _h;

            public decimal CallTest() => _h.Test();
        }
#pragma warning restore 649
#pragma warning restore 169

        public static void Main(string[] args)
        {
            Console.WindowWidth = 120;

            const int Count = 100 * 1000 * 1000;
            var wrapper1 = new HeavyStructWrapper();
            var wrapper2 = new HeavyStructWrapper2();

            Measure("wrapper1", () =>
            {
                for (int i = 0; i < Count; i++)
                {
                    wrapper1.CallTest();
                }
                return Count;
            });

            Measure("wrapper2", () =>
            {
                for (int i = 0; i < Count; i++)
                {
                    wrapper2.CallTest();
                }
                return Count;
            });

            Console.WriteLine("\r\nDone.");
            Console.ReadKey();
        }

        static void Measure(string name, Func<long> callback)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            var mem = GC.GetTotalMemory(true);
            var gc00 = GC.CollectionCount(0);
            var gc01 = GC.CollectionCount(1);
            var gc02 = GC.CollectionCount(2);

            var sw = Stopwatch.StartNew();
            var result = callback();
            sw.Stop();

            var mem2 = GC.GetTotalMemory(false);
            var gc10 = GC.CollectionCount(0);
            var gc11 = GC.CollectionCount(1);
            var gc12 = GC.CollectionCount(2);

            var memDelta = (mem2 - mem) / 1024.0;
            var gcDelta0 = gc10 - gc00;
            var gcDelta1 = gc11 - gc01;
            var gcDelta2 = gc12 - gc02;

            Console.WriteLine(
                "{0,25}: {1,5}ms, ips: {2,22:N} | Mem: {3,6:N2} kb, GC 0/1/2: {4}/{5}/{6} => {7,6}",
                name, sw.ElapsedMilliseconds, result / sw.Elapsed.TotalSeconds, memDelta, gcDelta0, gcDelta1, gcDelta2, result);
        }
    }
}
Отредактировано 07.01.2017 16:47 Sinix . Предыдущая версия .
минутка wtf
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.