Допустим, имеется некий массив, например:
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 } };
Все массивы реализуют IEnumerable (не generic), таким образом, при использовании этого интерфейса все элементы будут упакованы?
Вопрос актуален, например, при использовании Linq-операций Cast
Console.WriteLine(string.Join(" " , array.Cast
Ответ
Да, ситуация с многомерными массивами довольно печальная. Такой массив реализует IEnumerable, но не реализует IEnumerable
Вот простой бенчмарк (на основе BenchmarkDotNet), который показывает, что это действительно так:
[MemoryDiagnoser]
public class MultidimentionalAarrayTests
{
private int[,] m_multiArray = {{1, 2}, {3, 4}};
private int[] m_regularArray = {1, 2, 3, 4};
[Benchmark]
public int MultiArrayLast()
{
return m_multiArray.Cast
[Benchmark]
public int RegularArrayLast()
{
return m_regularArray.Last();
}
}
Результат:
Method | Mean | Error | StdDev | Gen 0 | Allocated |
--------------------------- |------------:|----------:|----------:|-------:|----------:|
MultiArrayLast | 1,166.97 ns | 23.229 ns | 51.473 ns | 0.0401 | 132 B |
RegularArrayLast | 51.29 ns | 1.250 ns | 3.686 ns | - | 0 B |
Мы тут видим кучку аллокаций: в первом случае - упакован каждый элемент, итератор в Cast
Поскольку многомерные массивы не реализуют обобщенный IEnumerable
public static class MultiDimentionalArrayEx
{
public static IEnumerable
Теперь мы можем добавить еще один бенчмарк, чтобы проверить результат:
[Benchmark]
public int MultiArrayWithAsEnumerable()
{
return m_multiArray.AsEnumerable().Last();
}
И вот окончательный результат:
Method | Mean | Error | StdDev | Gen 0 | Allocated |
--------------------------- |------------:|-----------:|-----------:|-------:|----------:|
MultiArrayLast | 1,115.45 ns | 31.0145 ns | 90.9603 ns | 0.0401 | 132 B |
RegularArrayLast | 46.11 ns | 0.1826 ns | 0.1525 ns | - | 0 B |
MultiArrayWithAsEnumerable | 161.74 ns | 3.2693 ns | 3.2109 ns | 0.0150 | 48 B |
Здесь мы видим, что есть выделение в куче двух итераторов (одного для метода расширения и еще одного для Enumerable.Last
Комментариев нет:
Отправить комментарий