C# спектакли, массив против диапазона из буфера памяти - PullRequest
1 голос
/ 07 февраля 2020

Я тестирую производительность использования стандартного массива C# против использования буфера памяти. Стандартный массив выигрывает. Я не понимаю, как стандартный массив быстрее, чем использовать диапазон из буфера памяти. В документации говорится, что буфер памяти предполагается использовать в высокопроизводительных сценариях ios. Я использую оптимизированную версию Release.

class Program
{
    private static void MemoryPoolTest(IMemoryOwner<long> owner)
    {
        for (var i = 0; i < 100; i++)
        {
            var innerCounter = 0;
            for (var j = 0; j < 1000; j++)
            {
                if (j % 3 == 0)
                {
                    owner.Memory.Span[innerCounter++] = DateTime.UtcNow.Ticks;
                }
            }
            var result = owner.Memory.Slice(0, innerCounter - 1);
        }
    }

    private static void ArrayTest()
    {
        for (var i = 0; i < 100; i++)
        {
            var innerCounter = 0;
            Span<long> array = new long[1000];
            for (var j = 0; j < 1000; j++)
            {
                if (j % 3 == 0)
                {
                    array[innerCounter++] = DateTime.UtcNow.Ticks;
                }
            }
            var result = array.Slice(0, innerCounter - 1);
        }
    }

    static void Main(string[] args)
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        var m = new List<long>();
        var a = new List<long>();
        var sw = new Stopwatch();
        using var owner = MemoryPool<long>.Shared.Rent(1000);
        for (var i = 0; i < 1000; i++)
        {
            sw.Restart();
            MemoryPoolTest(owner);
            sw.Stop();
            m.Add(sw.ElapsedTicks);
            sw.Restart();
            ArrayTest();
            sw.Stop();
            a.Add(sw.ElapsedTicks);
        }
        Console.WriteLine(m.Skip(10).Average());
        Console.WriteLine(a.Skip(10).Average());
    }
}

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Проблема в использовании owner.Memory.Span для каждой итерации. Присвоение Span переменной до итерации сокращает бесполезные операции, и BufferMemory выигрывает

class Program
{
    private static void MemoryPoolTest(Span<long> span)
    {
        for (var i = 0; i < 100; i++)
        {
            var innerCounter = 0;
            for (var j = 0; j < 1000; j++)
            {
                if (j % 3 == 0)
                {
                    span[innerCounter++] = DateTime.UtcNow.Ticks;
                }
            }
            var result = span.Slice(0, innerCounter - 1);
        }
    }

    private static void ArrayTest()
    {
        for (var i = 0; i < 100; i++)
        {
            var innerCounter = 0;
            Span<long> array = new long[1000];
            for (var j = 0; j < 1000; j++)
            {
                if (j % 3 == 0)
                {
                    array[innerCounter++] = DateTime.UtcNow.Ticks;
                }
            }
            var result = array.Slice(0, innerCounter - 1);
        }
    }

    static void Main(string[] args)
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        var m = new List<long>();
        var a = new List<long>();
        var sw = new Stopwatch();
        using var owner = MemoryPool<long>.Shared.Rent(1000);
        var span = owner.Memory.Span;
        for (var i = 0; i < 1000; i++)
        {
            sw.Restart();
            MemoryPoolTest(span);
            sw.Stop();
            m.Add(sw.ElapsedTicks);
            sw.Restart();
            ArrayTest();
            sw.Stop();
            a.Add(sw.ElapsedTicks);
        }
        Console.WriteLine(m.Skip(10).Average());
        Console.WriteLine(a.Skip(10).Average());
    }
}
0 голосов
/ 07 февраля 2020

A Span выделяется (или перемещается) в кучу (стек), A Memory<T> более вероятно из управляемой памяти.

Это зависит от конкретного процессора, но куча больше всего часто используется из маленькой памяти внутри ЦП, иногда называемой кешем, сегодня до 1 МБ или 2 МБ на ядро, что обеспечивает очень быстрый доступ, тогда как управляемая память выделяется в обычной ОЗУ. Может также кэшироваться, но не с высокой вероятностью.

...