新しいものを表示

なんかC#で普通に内部的なエラー処理なんかでも「例外発生させて、それを受け取って・・・」ってやってたけど、標準の例外処理の負荷を考えたらタプルなり専用の型なりでエラー情報を返す方がいいのか・・・><

Geminiに色々聞いたら「Rustが例外方式じゃなくてResult/Option方式なのは、エラー発生時の処理コストの問題も理由なんですよ」(超意訳)って教えてくれてなるほどなった><(?)

世の中の大量のソフトウェアがオーバーフローからのラップアラウンドでバグるの、システム任せでチェックするとこんなに重いならばいちいち何でもかんでもチェックなんてできないだろうしなるほどかも><;

"値の範囲をint32にしちゃって、内部はint64にすれば..."にしたら、オレンジ版の方が大幅に速くなった><;

System.Int32 ver. Elapsed Time: 1790 ms
Subrange ver. Elapsed Time: 217 ms

スレッドを表示

もしかして、C#では(?)、高確率でオーバーフローしまくる可能性がある掛け算をする時に、あらかじめ自前でオーバーフローするかどうかをコードで判断できるなら自前で判断をやってでも例外を発生を避けるほうが高速になる場合がある?><;

なんと、オレンジの元の実装でも、int32でcheckedでオーバーフローを空キャッチするコードよりはちょっと高速らしい・・・><;
オーバーフロー時の処理が重いのか><;

スレッドを表示

値の範囲をint32にしちゃって、内部はint64にすれば、自前の範囲チェックのみで済んでCPU側のラップアラウンドが発生しなくなるからuncheckで計算できて軽くなる・・・?><

スレッドを表示

原因分かった!><;
checkedブロックの中で掛け算するととんでもなく重い><;

スレッドを表示

・・・実はnintのほうは、最適化で中身が空になってたりするのかな?><

スレッドを表示

ちょっといじってみたけど、初期化とかじゃなく、マジでただの掛け算にこの時間のほぼすべてがかかってるっぽい><;

スレッドを表示

かなり前からC#に部分範囲型がない事を嘆く度にわりと馬鹿にされまくってたの、今こそ納得がいかない><

ていうかさっきGeminiにオレンジのアイディアについて聞いたときに、
"""精緻化型(Refinement Types)
Ariane 5の例で出された「部分範囲型」を究極まで突き詰めると、Refinement Types になります。 これは、int などの基本型に $x >= 0 && x < 65536$ のような制約(述語)を付与した型です"""
ってまさにそれが出てきた><

orange さんがブースト

(x: Int :| Positive) + 1 は Int ではあるが Int :| Positive にはならないので、改めてrefineしないとコンパイルエラー、なるほどね。

スレッドを表示
orange さんがブースト

値の検証もコンパイラにやらせよう: Scala 3でRefinement TypesやるにはIronっていうライブラリが良さそう - Lambdaカクテル blog.3qe.us/entry/2024/02/19/040745

オレンジがやってるのって結局のところ単なるRustの再発明なのかな?><

結局のところ、Rustのエラーハンドリングみたいなのを、こまめにする(Rust)か、後で一気にまとめてする(オレンジが思いついたやつ)かくらいの違いくらいしかない?><;

スレッドを表示

もしかしてそういうパターンで作れば、言語仕様上の工夫やIDEの支援すらもいらないのかな?><
(でも危ない部分用の型と安全な部分用の型の見分けがつきにくい?><;)

スレッドを表示

オレンジは思い付きでnullチェックを代用しだけど、まったく同じ発想で、『チェック前型とチェック後型』って発想を言語仕様に入れたら、ある時点まではエラーもありつつも投機的に計算して、ある時点で一気にチェックして『チェック後型』に明示的な型変換をする事で、そこから先は安全に使えるようにするって発想の実装をいろいろ作れて便利そうだけどどうなんだろう?><

古いものを表示
:realtek:

思考の /dev/null