閑古鳥

オールドプログラマの日記。プログラミングとか病気(透析)の話とか。

C#のRangeとIndex

C# 8.0 の新機能 - C# ガイド | Microsoft Docs

C# 8.0で追加されたRangeやIndexによって、配列の一部の要素を参照したいときに以下のように書けるようになりました。Rubyっぽい。

int[] arr = {0, 1, 2, 3, 4, 5};
arr[^1].Dump();    // => 5 (最後の要素が取れる)
arr[1..^1].Dump(); // => [1,2,3,4]

^1とだけ書くとSystem.Index型、1..2だとSystem.Range型で評価される。...はありません。

配列の添え字にRangeを渡した場合、RuntimeHelpers.GetSubArrayメソッドが呼ばれるみたいだけど、コピーを作成するみたいなのであまり効率は良くなさそう?

AsSpanメソッドを挟むと速くなるとか。雑に試してみました。

Method Mean Error StdDev Allocated
Sum_Index 85.88 ms 0.330 ms 0.309 ms 812 B
Sum_Linq 1,082.57 ms 2.199 ms 2.057 ms 96 B
Sum_Range 969.83 ms 1.186 ms 1.051 ms 799999256 B
Sum_Span 79.02 ms 0.333 ms 0.312 ms 6 B

Spanは普通にforループ回すよりも速いみたいです。すごい。

素数多くなるほどLINQは遅くなるのが厳しいですね。イテレータ噛ませているからある程度は仕方無いんですが…。