Почему производительность ToArray имеет такое поведение, Net Core 3.1? - PullRequest
3 голосов
/ 19 января 2020

Я приложил тесты памяти

Я отредактировал вопрос

Я тестировал ToArray и ToList метод на IEnumerable<int>, и я посмотрел яму от 530 до 800 тысяч на графике c. Я закрепил свой тестовый код:

 [MarkdownExporter, AsciiDocExporter, HtmlExporter, CsvExporter, RPlotExporter, PlainExporter] [MemoryDiagnoser]
    public class IntBenchmarks
    {
        private IEnumerable<int> EnumerableInts;


        [Params(
            // 10000 ... 1000000
        )]
        public int _count;

        public IntBenchmarks()
        {
            EnumerableInts = GetEnumerableInts();
        }


        private IEnumerable<int> GetEnumerableInts()
        {
            for (var i = 0; i < _count; i++)
            {
                yield return 1;
            }
        }


        [Benchmark]
        public void ToArrayInt()
        {
            var r = EnumerableInts.ToArray();
        }


        [Benchmark]
        public void ToListInt()
        {
            var r = EnumerableInts.ToList();
        }

    }

Кроме того, я знаю, что память выделяется (есть память для нового массива), когда _count равен 530000. Мне очень интересно, почему производительность лучше, когда память выделена. У меня есть тесты для IEnumerable класса, структуры, строки int, только IEnumerable из int имеет такое поведение


enter image description here

Я проверял это неоднократно

Тесты памяти: enter image description here

1 Ответ

0 голосов
/ 19 января 2020

В реальном IEnumerable, который не может быть приведен ни к чему другому, что вы используете с помощью метода итератора yield return, ToArray вызывает ToList, не потому что ToList быстрее, но более гибко, он подготовлен для обработки неизвестного количества данных. Мы должны избегать двукратного перечисления, что произойдет, если, например, использовать расширение Count().

ToArray () будет быстрее - если вы заранее знаете количество элементов. Это может быть в случае, если источником является ICollection - фактически единственная идея ICollection для поддержки этой функции - знание количества элементов в Advance.

Ваше измерение определено c чистым итераторам (с возвратом урожая). Если IEnumerable проверен на true, то есть Array, IList или ICollection, он довольно преобразуется и используется собственная реализация List.CopyTo и Array.CopyTo. Они не перечисляют IEnumerable. Просто чтобы подчеркнуть: list.ToList () и list.ToArray () или int []. ToList () или int []. ToArray () не будут отображать это поведение

Я не могу объяснить возможные различия .NET / Core.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...