><https://twitter.com/orange_in_spacehttps://pawoo.net/@orange_in_space
もしかして、C#では(?)、高確率でオーバーフローしまくる可能性がある掛け算をする時に、あらかじめ自前でオーバーフローするかどうかをコードで判断できるなら自前で判断をやってでも例外を発生を避けるほうが高速になる場合がある?><;
なんと、オレンジの元の実装でも、int32でcheckedでオーバーフローを空キャッチするコードよりはちょっと高速らしい・・・><;オーバーフロー時の処理が重いのか><;
値の範囲をint32にしちゃって、内部はint64にすれば、自前の範囲チェックのみで済んでCPU側のラップアラウンドが発生しなくなるからuncheckで計算できて軽くなる・・・?><
原因分かった!><;checkedブロックの中で掛け算するととんでもなく重い><;
・・・実はnintのほうは、最適化で中身が空になってたりするのかな?><
ちょっといじってみたけど、初期化とかじゃなく、マジでただの掛け算にこの時間のほぼすべてがかかってるっぽい><;
・・・・・・><
かなり前からC#に部分範囲型がない事を嘆く度にわりと馬鹿にされまくってたの、今こそ納得がいかない><
ていうかさっきGeminiにオレンジのアイディアについて聞いたときに、"""精緻化型(Refinement Types)Ariane 5の例で出された「部分範囲型」を究極まで突き詰めると、Refinement Types になります。 これは、int などの基本型に $x >= 0 && x < 65536$ のような制約(述語)を付与した型です"""ってまさにそれが出てきた><
形式検証の簡易版?><
(x: Int :| Positive) + 1 は Int ではあるが Int :| Positive にはならないので、改めてrefineしないとコンパイルエラー、なるほどね。
値の検証もコンパイラにやらせよう: Scala 3でRefinement TypesやるにはIronっていうライブラリが良さそう - Lambdaカクテル https://blog.3qe.us/entry/2024/02/19/040745
オレンジがやってるのって結局のところ単なるRustの再発明なのかな?><
結局のところ、Rustのエラーハンドリングみたいなのを、こまめにする(Rust)か、後で一気にまとめてする(オレンジが思いついたやつ)かくらいの違いくらいしかない?><;
もしかしてそういうパターンで作れば、言語仕様上の工夫やIDEの支援すらもいらないのかな?><(でも危ない部分用の型と安全な部分用の型の見分けがつきにくい?><;)
オレンジは思い付きでnullチェックを代用しだけど、まったく同じ発想で、『チェック前型とチェック後型』って発想を言語仕様に入れたら、ある時点まではエラーもありつつも投機的に計算して、ある時点で一気にチェックして『チェック後型』に明示的な型変換をする事で、そこから先は安全に使えるようにするって発想の実装をいろいろ作れて便利そうだけどどうなんだろう?><
動作はあってるけどメッセージの内容がバグってるね><;(引き算してるのにメッセージが足し算のコピペのままだね><;)
これは単にnullableなら未チェック、non-nullableなら範囲チェック済で安全って方式だけど、Roslynソースジェネレータを使ってnullable用の型とnon-nullable用の型で自動で名前をわけたら、もうちょっと見やすくなりそう><
C# の自作部分範囲型ちゃんと動く><
そもそも仕様にあわないものを作ってるんだから仕様にあうように実装するのは当然不可能という当然なあれなのかも><;
思考の /dev/null