Re[4]: быстрый ToEnumerable
От: hi_octane Беларусь  
Дата: 23.04.15 18:27
Оценка: 2 (1)
T>Т.е. большая нагрузка на кучу сохраняется.
T>Получается объект всё равно в кучке создается или просто при приведении к интерфейсу всё равно боксинг происходит?

В этом случае решарпер показал аж 3 боксинга. После того как я изменил код на использование stopwatch, сделал несколько проходов для устаканивания JIT, добавил GC.Collect, а твой сам-себе итератор поправил на класс чтобы ушли боксинги, получилось примерно так.

Итерация 3
Тест 0 запущен
Time: 3, Memory GC: 0, Memory WS: 0
Тест 1 запущен
Time: 1195, Memory GC: 483328, Memory WS: 0
Тест 2 запущен
Time: 782, Memory GC: 786432, Memory WS: 0
Тест 3 запущен
Time: 551, Memory GC: 353824, Memory WS: 8192
Тест 4 запущен
Time: 388, Memory GC: 920240, Memory WS: 4096


Т.е. сам-себе итератор сделанный классом порвал массив. Код под катом.

  Скрытый текст
        private const int ITERATION_COUNT = 10000000;

        static Stopwatch stopwatch = new Stopwatch();

        static void Main(string[] args)
        {
            var tests = new Func<int>[] { Test0, Test1, Test2, Test3, Test4};

            for(var i = 0; i < 4; i++)
            {
                Console.WriteLine("Итерация {0}", i);

                for(var j=0; j<tests.Length;j++)
                {
                    RunTest(j, tests[j]);

                    GC.Collect(0, GCCollectionMode.Forced);
                    Thread.Sleep(1000);
                }                
            }
                        
            //Test0();
            //Test1();
            //Test2();
            //Test3();
            //Test4();
            
        }
        
        static void RunTest(int num, Func<int> test)
        {
            Console.WriteLine("Тест {0} запущен", num);
            var memoryGC = GC.GetTotalMemory(false);
            var memoryWS = Environment.WorkingSet;

            stopwatch.Reset();
            stopwatch.Start();
            test();
            stopwatch.Stop();

            Console.WriteLine("Time: {0}, Memory GC: {1}, Memory WS: {2}", stopwatch.ElapsedMilliseconds,
                              GC.GetTotalMemory(false) - memoryGC, Environment.WorkingSet - memoryWS);
            
        }


        private static int Test0()
        {
            var value = new Random(DateTime.Now.Millisecond).Next();
            for(var i = 0; i < ITERATION_COUNT; i++)
                value += value;
            return value;
        }

        private static int Test1()
        {
            var value = new Random(DateTime.Now.Millisecond).Next();
            for(var i = 0; i < ITERATION_COUNT; i++)
                value += value.AsEnumerable1().Sum();
            return value;
        }

        private static int Test2()
        {
            var value = new Random(DateTime.Now.Millisecond).Next();
            for(var i = 0; i < ITERATION_COUNT; i++)
                value += value.AsEnumerable2().Sum();
            return value;
        }

        private static int Test3()
        {
            var value = new Random(DateTime.Now.Millisecond).Next();
            for(var i = 0; i < ITERATION_COUNT; i++)
                value += value.AsEnumerable3().Sum();
            return value;
        }

        private static int Test4()
        {
            var value = new Random(DateTime.Now.Millisecond).Next();
            for(var i = 0; i < ITERATION_COUNT; i++)
                value += value.AsEnumerable4().Sum();
            return value;
        }
    }

    public static class Helper
    {
        public static IEnumerable<T> AsEnumerable1<T>(this T value)
        {
            yield return value;
        }

        public static IEnumerable<T> AsEnumerable2<T>(this T value)
        {
            return Enumerable.Repeat(value, 1);
        }

        public static IEnumerable<T> AsEnumerable3<T>(this T value)
        {
            return new[] { value };
        }

        public static IEnumerable<T> AsEnumerable4<T>(this T value)
        {
            return new Single<T>(value);
        }

    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.