[過去ログ]
Rust part15 (1002レス)
Rust part15 http://mevius.5ch.net/test/read.cgi/tech/1652347700/
上
下
前次
1-
新
通常表示
512バイト分割
レス栞
抽出解除
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
502: デフォルトの名無しさん [sage] 2022/06/06(月) 23:15:40.43 ID:HuPaBwwV >>481 1.5倍も差があるのは妙だな Rustでは最適化されるのでジェネリックで書こうがそんな差は出ないはず そのベンチマークの仕方がおかしい可能性があるので ジェネリックか否か、check_addか+か、Option利用か否か、など5つのコードで順に調べてみた ベンチマーク使用コード https://gist.github.com/rust-play/18d303c3ec79c19c4285ed190e5b2562 (1) ジェネリック + checked_add + Option + successors 版: 元の>>295と完全に同じコード (2) BigUint + checked_add + Option + successors 版: (1)のTをBigUintへ (3) BigUint + add + Option + successors 版: (2)のchecked_addを'+'へ (4) BigUint + add + Option削除 + successors 版: (3)の変数Optionを削除 (5) BigUint + add + Option削除 + from_fn 版: (4)のsuccessorsをfrom_fnへ 結果 test bench_1 ... bench: 619,527 ns/iter (+/- 18,257) test bench_2 ... bench: 620,293 ns/iter (+/- 23,787) test bench_3 ... bench: 624,149 ns/iter (+/- 24,388) test bench_4 ... bench: 626,810 ns/iter (+/- 20,343) test bench_5 ... bench: 619,675 ns/iter (+/- 30,977) 結論 いずれも誤差の範囲でほぼ同一結果 Rustではジェネリックで書いても最適化される BigUintでchecked_addやその結果のOptionを使っても最適化される したがってi8からBigUintまで任意に動作する>>295のジェネリックコードで問題なし、となる http://mevius.5ch.net/test/read.cgi/tech/1652347700/502
503: デフォルトの名無しさん [] 2022/06/06(月) 23:58:37.28 ID:hMQAMrNY >>502 Rust凄いな ジェネリックもOptionも何でも最適化してくれるとは改めてRustの素晴らしさを実感 http://mevius.5ch.net/test/read.cgi/tech/1652347700/503
504: デフォルトの名無しさん [sage] 2022/06/07(火) 00:13:51.07 ID:GvuMwmTL >>502 そのやり方で差が出ないのはchecked_addと同じようにcloneが発生するタイプのaddが使われてるからだよ ジェネリックにしても差が出ない場合もあれば差が出る場合もあるということ http://mevius.5ch.net/test/read.cgi/tech/1652347700/504
505: デフォルトの名無しさん [] 2022/06/07(火) 00:16:51.98 ID:y2mAB4fu >>502 やはり同じになったか 既に>>478が指摘しているように元のコードとイテレータ同士で比較ベンチを取ろうとしないから>>475を怪しいと思ってた ちゃんと比較ベンチすれば最適化されて同じ速さになることを知っての狼藉だったりして http://mevius.5ch.net/test/read.cgi/tech/1652347700/505
507: デフォルトの名無しさん [] 2022/06/07(火) 00:19:44.22 ID:y2mAB4fu >>504 どういうこと? 具体的に>>502の各コードよりも速いコードを書けるってこと? そのコードを示せない限り>>502のベンチ結果を覆せない http://mevius.5ch.net/test/read.cgi/tech/1652347700/507
508: デフォルトの名無しさん [] 2022/06/07(火) 00:35:03.04 ID:z0w37Unr >>506 君は全く別の問題にすり替えて誤魔化している >>502のようにイテレーター同士でベンチマークをとるべき http://mevius.5ch.net/test/read.cgi/tech/1652347700/508
512: デフォルトの名無しさん [] 2022/06/07(火) 01:35:52.48 ID:gaZATsj9 この件はRustにとって重要なことだから口を挟むが、 Rustではジェネリックで書いてもmonomorphizationによって各型で書いた時と同じコードになる。 だから標準ライブラリの大半はジェネリックに書かれている。 そしてSomeなどのOptionは最適化できる時は綺麗に消えるため、 BigIntのchecked_addのように常にSomeを返す時も最適化でOptionは消えると考えられる。 いずれも抽象的に書けるのに動かすとC並に速いというRustの長所である。 つまり、>>502の結果が出たことはそれらが実証付けられたことになる。 しかし、以前からジェネリックは無駄とか遅いとかRustの長所に反する主張をする人がいるので気になっていた。 今回もRustのジェネリックは遅いと主張するために、 >>506のように、完全に異なるもの同士を比較したり、 >>511のように、Rcを返すという別仕様のものにしてまで、ジェネリックは遅いと主張し出した。 反Rustか反ジェネリックの立場なのかもしれないが、そういう捏造や詐欺のようなことはよくない。 http://mevius.5ch.net/test/read.cgi/tech/1652347700/512
515: デフォルトの名無しさん [] 2022/06/07(火) 07:03:55.78 ID:/+rlx4fZ >>511 そのコードはイテレータ内部で無理にunwrapしているためこれだけでpanicしてしまう let mut iter = fibonacci_biguint_iter(); let first = iter.next(); let second = iter.next(); 実行結果 thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:23:30 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace これでは反証コードになっていないので ちゃんとimpl Iterator<Item = BigUint>を返すコードを書いたほうがいい >>514 その無駄なcloneとは何? ベンチ>>502のジェネリックコードを含めた5つのコードを見てみたが無駄なcloneは見当たらなかった それらよりもベンチで速いコードが出てこない現状をみると無駄は無いのではないか あと、BigUintを使うまでもない需要も多いのだからジェネリックに書かれたコード一つで十分と感じる http://mevius.5ch.net/test/read.cgi/tech/1652347700/515
535: デフォルトの名無しさん [] 2022/06/07(火) 23:25:02.45 ID:lnwubCy8 >>532 フィボナッチは単なる題材に過ぎないことを理解できていないのはヤバいぞ 例えば>>529の定数畳み込みや>>502のジェネリックやOptionが最適化される話などが本題 単純だが単純過ぎない題材の例としてたまたまフィボナッチ数列が使われている http://mevius.5ch.net/test/read.cgi/tech/1652347700/535
539: デフォルトの名無しさん [sage] 2022/06/08(水) 01:40:47.24 ID:C5b6ywPX https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=5180fadf9fda409e0456042fc1bccd8e 遅くなるの分かりきってたから出し渋ったつもりだったけど普通に速かったわwwwメンゴメンゴ test bench_1 ... bench: 426,277 ns/iter (+/- 1,804) test bench_fast ... bench: 350,928 ns/iter (+/- 2,760) 一応criterion版も貼っとく >>502で提起されたベンチマーク不適切説の真偽が気になるなら是非実行してみてくれ https://gist.github.com/rust-play/3bd45555b9e6faef2b1426712e4e7601 http://mevius.5ch.net/test/read.cgi/tech/1652347700/539
541: デフォルトの名無しさん [sage] 2022/06/08(水) 02:17:57.20 ID:aUi5KtMm >>539 君のベンチはいつも何と何の違いを比較しようとしているのかよくわからない 一方で>>502は何と何を比較するのかを明確にした上で各項目毎に段階を経て比較しているから 仮にベンチで違いがあればその要因が明確となり知見が得られる比較となっている 君の投稿からは結果に対して何が要因なのか知見が全く得られない http://mevius.5ch.net/test/read.cgi/tech/1652347700/541
542: デフォルトの名無しさん [sage] 2022/06/08(水) 02:29:17.13 ID:aUi5KtMm >>540 まず速度差がそのおっしゃっているchecked_addによるものなのかどうかを明確にしたほうが良いかと思う >>502を見てみると(2)→(3)がchecked_addの有無になっているがベンチは同じ その結果からchecked_addは関係ないのではないか? http://mevius.5ch.net/test/read.cgi/tech/1652347700/542
545: デフォルトの名無しさん [sage] 2022/06/08(水) 06:22:34.20 ID:2tL4qRNc >>544 元と同一コードを含む5種類のベンチ>>502のコードを見たけど 特に汚いコードは見当たらないんじゃない? もしあるならば具体的にどの部分なのかを言ったほうがいいと思うよ http://mevius.5ch.net/test/read.cgi/tech/1652347700/545
553: デフォルトの名無しさん [sage] 2022/06/08(水) 15:00:02.66 ID:0R8j40RZ >>502 「1.5倍も差があるのは妙だな Rustでは最適化されるのでジェネリックで書こうがそんな差は出ないはず」 これがそもそもおかしい、最適化されようが何だろうが生成されるコードは違うのでMIRなりdisamなりでインストラクション単位で目視すれば一発だろ。ベンチを取る以前の思い込み低レベルな話 そしてほぼ最適化された無駄のないコードだったとしても >>523 ここ5年程度のCPUでは64バイトのDSB境界を持つ小さなループ呼び出しなどが単一のμopsキャッシュに収まる場合があるがコードの配置によって異なり1.5倍程度の差が出ても不思議じゃない。 言ってるのに全く聞かない http://mevius.5ch.net/test/read.cgi/tech/1652347700/553
554: デフォルトの名無しさん [sage] 2022/06/08(水) 15:48:23.76 ID:kiLfNcoT >>553 その件は1.5倍差あった>>481がイテレータと関数を比較するという大チョンボをしていたことが原因と判明済 そしてジェネリックか否か自体では速度に差が出ないことを>>502のベンチが証明済 http://mevius.5ch.net/test/read.cgi/tech/1652347700/554
557: デフォルトの名無しさん [sage] 2022/06/08(水) 17:31:51.50 ID:H0oyRmek 一般的に、数列を順に求めるイテレータと、 そのうちの特定の数だけを求める関数とでは、 オーダー問題もアルゴリズムも変わってくるため、 >>481はまた別の問題となっている。 イテレータ同士の比較で1.5倍となっていないことからも、 異なる問題であると理解できるはず。 >>556 ジェネリックとノンジェネリックに速度差が無いことは、 >>502で既に示されたのだから、 ジェネリックかどうかは一切関係ないと思う。 ジェネリックとは別の問題。 http://mevius.5ch.net/test/read.cgi/tech/1652347700/557
558: デフォルトの名無しさん [sage] 2022/06/08(水) 18:18:03.20 ID:cKPONsWM >>557 >>502はジェネリックでも実現できるコードをノンジェネリックにしただけ ノンジェネリックならadd_assign, mem::swap, cloneで>>502のいずれよりも速いコードが書けるが ジェネリックだとchecked_addを使わざるを得ず同じことが実現できない http://mevius.5ch.net/test/read.cgi/tech/1652347700/558
567: デフォルトの名無しさん [sage] 2022/06/08(水) 22:52:52.99 ID:C5b6ywPX このままでは誰も気付かなさそうなのでここでネタばらし >>539のcriterion版ですがこちらで動かすとこうなりました fibonacci_iter_1 time: [7.3605 ms 7.3655 ms 7.3711 ms] Found 9 outliers among 100 measurements (9.00%) 1 (1.00%) high mild 8 (8.00%) high severe fibonacci_biguint_iter time: [7.5944 ms 7.5967 ms 7.5992 ms] Found 2 outliers among 100 measurements (2.00%) 1 (1.00%) high mild 1 (1.00%) high severe 同程度に遅くなってしまいました 理由は>>548の通り、せっかく減らしたcloneをイテレータ化するために戻さざるを得なかったからです 一見非ジェネリックのほうが速い結果が出たのは、criterion版がN=50000としていたのに対して、 test crate版は最初に貼られたN=10000から変えずにやっていたためでした criterion版をN=10000で、test crate版をN=50000で計測してみると大体同じような結果になりました N<2^15あたりまでは非ジェネリックのほうがちょっとだけ速いみたいですが、まあ誤差の範疇かと思います そういうわけで>>539で非ジェネリックのほうが速いと主張したのは嘘です 本気で信じちゃった人はごめんね 最初はcriterionとtest crateの差だと早とちりしたため、ベンチマーク不適切説とか勿体ぶった書き方をしてました >>502で根拠も無く疑いをかけたのに対するカウンターのつもりで黙ってたんですが、不発になっちゃいました まあでもtest crateってwarm upもしないしサンプル数固定だし、その結果ひどい場合だと>>511なんか相対誤差10%超えてるし criterion使ったほうがいいよってのは大筋では間違ってないよね 最後に+=でイテレートするこれだけ貼っとくから 某おじはこれに相当する性能のジェネリックなイテレータが書けるまでそういったクソどうでもいい執着に人を付き合わせるんじゃないぞ https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=76cd0aad53f19888900a4b450fd078c5 http://mevius.5ch.net/test/read.cgi/tech/1652347700/567
573: デフォルトの名無しさん [sage] 2022/06/09(木) 09:43:05.84 ID:m8hzuB37 >>567 結局ジェネリックに書いても非ジェネリックでも速さはほぼ同じなのかよ どんな方法で書いても結果を返すためにclone相当が最低1回は必要で >>502のジェネリック版はclone相当がchecked_addでの1回のみだからこれ以上は速くできないってことか http://mevius.5ch.net/test/read.cgi/tech/1652347700/573
メモ帳
(0/65535文字)
上
下
前次
1-
新
書
関
写
板
覧
索
設
栞
歴
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.039s