ものがたり(旧)

atsushieno.hatenablog.com に続く

beware stackalloc

stackallocは速い。どんな感じに速いかは、以前にakirameiさんが実験しているのを参考にして頂ければと思う[*1]。今さらではあるけど、monoチームのoptimizationキチ○イBenがこれを使って最適化を試みて、実際かなりの数値的成果を上げた。

でも、それはしばらくしてrevertされた。

stackallocはunmanaged codeなので、managed codeであれば行われるべき各種のチェックが行われないことになってしまう。これが数ヶ所であればまだメンテできるけど、FCLの数百・数千ヶ所にわたったらどうなるだろうか。unsafeなコードは、基本的には避けるべきものなのだ。

[*1]
ただ、このサンプルコードでは、GCへの登録に違いが生じる(であろう)配列の確保と、配列境界チェックを伴う/伴わない要素アクセス[*1]の2つが問われている。おそらく配列の要素数によって傾向が変わるはずだ。

Lengthプロパティがローカル変数よりも高速である理由が配列境界チェック(以下ABCD)である。たとえばmeiさんのコードの「配列とローカル変数」のセクションを

int len = loop;
から
int len = a.Length;
に変えてみれば、Lengthプロパティでiterateした場合とほとんど代わらないパフォーマンスが出る。これはJITによるloop変数のトラッキング次第では、同じようにABCDすることもできるはずだ。ただ、JITだってそんなに複雑なコードチェックが出来るわけではないから(そんなことしてたらJITじゃなくなってしまうので)、実際には多分ありえない最適化なんだろう。