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);
}
}
|
| |