1 名前:デフォルトの名無しさん mailto:sage [2022/05/12(木) 18:28:20.99 ID:cuIcFT6k.net] 公式 https://www.rust-lang.org/ https://blog.rust-lang.org/ https://github.com/rust-lang/rust Web上の実行環境 https://play.rust-lang.org 日本語の情報 https://rust-jp.rs/ ※Rustを学びたい人はまず最初に公式のThe Bookを読むこと https://doc.rust-lang.org/book/ ※Rustを学ぶ際に犯しがちな12の過ち https://dystroy.org/blog/how-not-to-learn-rust ※Rustのasyncについて知りたければ「async-book」は必読 https://rust-lang.github.io/async-book/ ※C++との比較は専用スレへ C++ vs Rust https://mevius.5ch.net/test/read.cgi/tech/1619219089/ ※次スレは原則>>980 が立てること 前スレ Rust part14 https://mevius.5ch.net/test/read.cgi/tech/1644596656/
474 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 10:54:21.85 ID:ULNisafI.net] >>460 ブログへのリンクやアップデートはややマンネリ気味だけど 今週のcrateはいつもチェックしてる
475 名前:デフォルトの名無しさん [2022/06/05(日) 14:57:13.62 ID:1ZIcYX0i.net] >>467 そういう話をしたいのにRustと関係ない話や批判で荒らす連中がうざい Rustの話ならば最新動向から初心者の質問まで何でも歓迎 しかし他人叩きしている連中は邪魔
476 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 17:36:49.26 ID:kdHlti+w.net] 可読性や汎用性を犠牲にしてもfindがpositionより優位に速いとか ユースケース次第ではデメリットを補うだけのメリットがあるなら多少汚くても受け入れられる フィボナッチの>>202 と比較対象の>>181 や>>189 も同様
477 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 17:53:32.33 ID:uQ7Of1B3.net] 速度はベンチを取ってから ユースケースは具体的に示してから そういうことを主張してください そして本当に互いのやり方にメリデメがあると認めているのなら、>>295 のような他人叩きはやめましょうね
478 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 18:25:46.65 ID:Zl7Pb69A.net] まーたふぃぼなっち言ってるw バカのひとつ覚えすなあw
479 名前:デフォルトの名無しさん [2022/06/05(日) 18:50:30.04 ID:1ZIcYX0i.net] >>470 その>>295 は他人叩きではないだろう そのアルゴリズムではBigIntで無駄なコピーが発生するというRustで気をつけるべき技術的な問題の指摘にみえる そして回避コードもきちんと示しているのでそういう書き込みは歓迎
480 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 21:53:01.43 ID:ZauVJiyh.net] >>470 何のメリットもなく汚くしてるだけだから受け入れられないという話だったんだが
481 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 22:11:06.61 ID:ZR9IOkh3.net] ジェネリックのフィボナッチや ジェネリックのカウントアップみたいな 架空のユースケース
482 名前:フ話題はもういいよ [] [ここ壊れてます]
483 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 22:14:01.51 ID:uQ7Of1B3.net] https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=41e1df59aeafe6f45fccaa192941d6d1 iter1とiter2は>>295 からの引用 Ryzen 7 3700Xで計測 ジェネリクスへのこだわりを捨てればこのくらいは速くできるよ fib_iter1 time: [7.2754 ms 7.2824 ms 7.2907 ms] Found 2 outliers among 100 measurements (2.00%) 1 (1.00%) high mild 1 (1.00%) high severe fib_iter2 time: [7.8536 ms 7.8678 ms 7.8818 ms] fib_biguint time: [4.9757 ms 4.9784 ms 4.9812 ms] Found 5 outliers among 100 measurements (5.00%) 5 (5.00%) high mild Playgroundでもベンチマークできればいいのになあ
484 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 22:14:34.17 ID:IymwRCap.net] 「RustとC++を学ぼうと思ってるプログラミング初心者です。」(架空)
485 名前:デフォルトの名無しさん [2022/06/05(日) 22:24:27.68 ID:+fEwSMrP.net] どの場でも同じだが 「技術的な話題と技術的な指摘」 「他者の話題と他者への攻撃」 この違いがわからず後者を行なうダメ人間のせいで場が荒れる
486 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 22:25:12.37 ID:xgxgbUCt.net] >>475 それは流石に比べる対象が違うんじゃ? ノンジェネリック版もイテレータを返すか ジェネリック版をフィボナッチ数を直接返すようにして比べないと
487 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 22:36:45.16 ID:4HXc2Nfq.net] >>475 playgroundみたいな環境でベンチマークやれたとしても結果が安定しないのでは
488 名前:デフォルトの名無しさん [2022/06/05(日) 22:40:18.97 ID:+fEwSMrP.net] >>475 純粋にジェネリックか否かの比較をしたいならばadd_assignとaddの違いなども含めて条件を全て揃えたほうがよい 元がiter::successorsを使っているならば非ジェネリック版も同じくそれで揃えてみてはどうか
489 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 23:17:38.06 ID:uQ7Of1B3.net] >>478 >>480 https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=4f477ec7bc08ea9f61f565c00beb0d19 ジェネリックなほうをできる限り揃えたけどこれでいいかい? CheckedAddでadd_assignする方法だけ無さそうだったからアレになってるけど fib_generic time: [7.4054 ms 7.4164 ms 7.4275 ms] Found 1 outliers among 100 measurements (1.00%) 1 (1.00%) high mild fib_biguint time: [4.9527 ms 4.9591 ms 4.9655 ms]
490 名前:デフォルトの名無しさん mailto:sage [2022/06/05(日) 23:34:45.61 ID:MGWqyCtZ.net] >>477 > 後者を行なうダメ人間 そういうのは一定数いるからスルーしてくださいな...
491 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 00:32:35 ID:m7d3UK5s.net] イテレータで計測してみたけど >>295 のoption::takeだとcloneしても速度変わらないな https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=283e5cd13159cab00fcc68d56952df01
492 名前:デフォルトの名無しさん [2022/06/06(月) 02:33:06.91 ID:ETmHHhEk.net] >>483 そういう比較はそれ以外の部分のコードを揃えないと何が要因なのか判断できないよ
493 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 03:21:12.98 ID:CfMv9iPR.net] Rustってフィボナッチ専用言語みたいだな
494 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 12:48:39.09 ID:fwdLGVHm.net] >>481 addがchecked_addになることで最適化が妨げられてるみたい 結局複オジが言ってたことは全部間違いだった
495 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 14:47:49.79 ID:bWO8YoN9.net] premature optimizationとpremature abstructionの典型例 ・具体的なユースケースを想定しない ・トレードオフを考えない ・誰も求めてない抽象化 ・計測を伴わない思い込み最適化 コードの汚さと悉く間違った主張の根っこは同じ
496 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 15:32:14.02 ID:eTH/ySe7.net] 複オジのおかげでいろんな教訓が再認識できて良かったね 反面教師の鑑 めでたしめでたし
497 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 15:53:42.58 ID:c+f9iTO8.net] >>487 なるほど 「早すぎる抽象化 × 早すぎる最適化 => 汚コード」ってことか これは身に覚えがありまくる
498 名前:481 mailto:sage [2022/06/06(月) 16:16:13.39 ID:lWIakgkT.net] >>486 正確に言えば 問題はCheckedAdd::checked_add()はselfもotherも参照で取るから、BigUintだと内部で1回clone()されてしまうということなのよね 一方でadd_assignは(桁があふれない限り)in-placeにやるから、その分のコストが発生しない だから(compiler optimizationという意味での)最適化以前の問題だよ https://mevius.5ch.net/test/read.cgi/tech/1509028624/153 ↑のコードも参考にどうぞ C++で二項演算子をオーバーロードするときのイディオムです これを思い出しながら書きました
499 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 16:52:12.73 ID:yU0i67fk.net] >>490 ソース見るところ勘違いしてた 確かにaddでも&self使えばclone入るからchecked_add並みに遅くなった checked_addにownedのselfを取るバージョンが追加されれば改善するだろうけど trait定義からして対応するつもりのないユースケースかもね
500 名前:デフォルトの名無しさん [2022/06/06(月) 16:57:14 ID:+9236oDl.net] >>491 CheckedAddAssignを導入すれば全て解決しそうだな
501 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 17:23:25 ID:V1HrdzSd.net] 必要ならextension traitを書けばいい そこまでしてジェネリックにする価値があるとは思えないけど
502 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 18:19:44.52 ID:fWB2qr5d.net] リーナスさんから受けたパニックのありがたい指摘って結局どうなったん?
503 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 20:58:23.31 ID:gJyU9Hxy.net] 放置されてんじゃないの? コンパイラがパニック起こさないように変えられたって聞かないし
504 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 21:04:20.00 ID:fWB2qr5d.net] パニックにならないオプションくらい作ってもいい気もするけどね
505 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 21:29:53.43 ID:qARo1+y7.net] パニック自体はもう1年前くらいに修正済み 今はv7 patchまで来ていて大きな懸念も出ていないから そろそろマージされてもおかしくはない
506 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 21:51:13.91 ID:gJyU9Hxy.net] リーナスレベルに行く前に誰も問題視してなくて指摘もされてないんだろうか みんなガバガバなんだな panic前提のコーディング
507 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 22:44:51.98 ID:Yvz8OCum.net] try_reserveはstabilizeされてるよ
508 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 23:01:32.72 ID:aWO23bGN.net] >>498 リーナスが最終承認だけするイメージなんかな? LKML読めば分かるけど、普通にパッチ投げるたびに突っ込んでくるよ
509 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 23:06:15.51 ID:2Zdu7NAR.net] ジェネリックフィボナッチと同程度にどうでもいい
510 名前:デフォルトの名無しさん mailto:sage [2022/06/06(月) 23:15:40.43 ID:HuPaBwwV.net] >>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 のジェネリックコードで問題なし、となる
511 名前:デフォルトの名無しさん [2022/06/06(月) 23:58:37.28 ID:hMQAMrNY.net] >>502 Rust凄いな ジェネリックもOptionも何でも最適化してくれるとは改めてRustの素晴らしさを実感
512 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 00:13:51.07 ID:GvuMwmTL.net] >>502 そのやり方で差が出ないのはchecked_addと同じようにcloneが発生するタイプのaddが使われてるからだよ ジェネリックにしても差が出ない場合もあれば差が出る場合もあるということ
513 名前:デフォルトの名無しさん [2022/06/07(火) 00:16:51.98 ID:y2mAB4fu.net] >>502 やはり同じになったか 既に>>478 が指摘しているように元のコードとイテレータ同士で比較ベンチを取ろうとしないから>>475 を怪しいと思ってた ちゃんと比較ベンチすれば最適化されて同じ速さになることを知っての狼藉だったりして
514 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 00:17:18.96 ID:YQOkxy3N.net] https://gist.github.com/rust-play/8caca28378745b36aaba5358d2a54fe8 test bench_1 ... bench: 426,714 ns/iter (+/- 5,563) test bench_fast ... bench: 201,510 ns/iter (+/- 2,926) Criterion の使い方が分からなかったのかな
515 名前:デフォルトの名無しさん [2022/06/07(火) 00:19:44.22 ID:y2mAB4fu.net] >>504 どういうこと? 具体的に>>502 の各コードよりも速いコードを書けるってこと? そのコードを示せない限り>>502 のベンチ結果を覆せない
516 名前:デフォルトの名無しさん [2022/06/07(火) 00:35:03.04 ID:z0w37Unr.net] >>506 君は全く別の問題にすり替えて誤魔化している >>502 のようにイテレーター同士でベンチマークをとるべき
517 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 00:38:00.86 ID:wvlfxzyf.net] まーたすがすがしいまでの自演だなぁ
518 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 00:39:26.17 ID:r6MnfEMB.net] >>507 >>504 の指摘の何が分からないの?
519 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 01:10:53.92 ID:YQOkxy3N.net] https://gist.github.com/rust-play/bde9b95f9bfe4de77fad841db30222c7 test bench_1 ... bench: 420,671 ns/iter (+/- 53,102) test bench_fast ... bench: 219,091 ns/iter (+/- 1,147) こんな汚ないことしてまでイテレータになんかしたくないんだけど どうせ次の文句も大体予想付くし
520 名前:デフォルトの名無しさん [2022/06/07(火) 01:35:52.48 ID:gaZATsj9.net] この件はRustにとって重要なことだから口を挟むが、 Rustではジェネリックで書いてもmonomorphizationによって各型で書いた時と同じコードになる。 だから標準ライブラリの大半はジェネリックに書かれている。 そしてSomeなどのOptionは最適化できる時は綺麗に消えるため、 BigIntのchecked_addのように常にSomeを返す時も最適化でOptionは消えると考えられる。 いずれも抽象的に書けるのに動かすとC並に速いというRustの長所である。 つまり、>>502 の結果が出たことはそれらが実証付けられたことになる。 しかし、以前からジェネリックは無駄とか遅いとかRustの長所に反する主張をする人がいるので気になっていた。 今回もRustのジェネリックは遅いと主張するために、 >>506 のように、完全に異なるもの同士を比較したり、 >>511 のように、Rcを返すという別仕様のものにしてまで、ジェネリックは遅いと主張し出した。 反Rustか反ジェネリックの立場なのかもしれないが、そういう捏造や詐欺のようなことはよくない。
521 名前:デフォルトの名無しさん [2022/06/07(火) 01:49:10.77 ID:eprvoL3W.net] >>512 同意
522 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 03:36:34.68 ID:hBVbMSyF.net] >>512 ジェネリクスが無駄だの遅いだのはコード生
523 名前:ャの話ではなくてコードのメンテナンスコスト含めた全体の話では 例えば今回ジェネリックなコードで無駄なcloneを避けるためには CheckedAddAssign といった trait を用意し、各整数型に実装するという余計な手間が発生する また、各整数に追加のtraitを実装したとしても固定長の整数型ではすぐに桁あふれしてしまうから、実質BigUintの実装しか意味がないものになる だったら最初からジェネリックにせずBigUintで実装するか、BigUintやBigIntといった桁あふれしない型だけを対象にすればよい ジェネリクスの良さを語りたいならもっと良い例があるんじゃないの [] [ここ壊れてます]
524 名前:デフォルトの名無しさん [2022/06/07(火) 07:03:55.78 ID:/+rlx4fZ.net] >>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を使うまでもない需要も多いのだからジェネリックに書かれたコード一つで十分と感じる
525 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 08:13:15.84 ID:AZaNrbV3.net] >>503 それはLLVMのおかげじゃない? 他言語でできないRustならではの優位点てあったっけ?
526 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 08:54:11.67 ID:99FzOzNU.net] Rustで抽象オブジェクト作るのってどうやんの?
527 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 08:59:47.84 ID:do0qCmU/.net] >>517 Box<dyn ...>のこと?
528 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 11:56:38.96 ID:99FzOzNU.net] >>518 C系だと構造体にtypeフィールド作って定数入れてその定数の値に応じて呼び出す関数変えるみたいなことやるんだけど インタプリタの動的オブジェクトみたいなもの Rustでもtypeフィールで条件分岐するのが普通?
529 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 12:28:57.89 ID:do0qCmU/.net] >>519 その用法ならたぶんenumですかね https://doc.rust-jp.rs/book-ja/ch06-01-defining-an-enum.html
530 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 12:30:31.93 ID:mvWCmBcR.net] ファントムなんとかを使うんじゃないのか?
531 名前:デフォルトの名無しさん [2022/06/07(火) 12:50:46.76 ID:1EDCqMQN.net] 抽象オブジェクトと検索して出てくる例みたいなのをRustでやるならこうだな enum Object { Integer(i32), Float(f32), 文字列(String), Null, } use Object::{Integer, Float, 文字列, Null}; impl Object { fn hello(&self) { match self { Integer(i) => println!("Hello, Intger {i} です"), Float(f) => println!("Hello, Float {f} です"), 文字列(s) => println!("こんにちは、文字列 {s} です"), Null => println!("Nullです"), } } } fn main() { let object_list = [Integer(12345), Float(67.89), 文字列("ABC".into()), Null]; for object in &object_list { object.hello(); } }
532 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 13:15:30.50 ID:1v+TnHgu.net] gccではなくg++とかだとフィボナッチ数列とかは演算しないように最適化される場合がある。 Rustのようにイグノーベルの遊びのコンピューターサイエンスのようなコードをこねくり回して気持ち悪く長くて自己満足オナニーコードになるぐらいだったら 部分的にmasmで書いたほうがマシ(速度的にも、メンテナンス性も) またRustはLLVMに執着しすぎてgccのような最適化はまだされてない、フィボナッチ数列とかのしょーもない一般的なアルゴリズムは CPUキャッシュに乗るのにマシンコードのセクションの結果が64kbに成らなかったり
533 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 13:48:18.23 ID:99FzOzNU.net] >>620-522 ありがとう
534 名前:デフォルトの名無しさん [2022/06/07(火) 14:15:55.18 ID:uuz77ncq.net] >>523 演算しないように最適化されるとか意味不明 演算はどこかで必ず発生する コンパイル時点で演算してしまう定数化のことならばRustでも当然できる const fn fibonacci(n: usize) -> usize { const fn f(n: usize, a: usize, b: usize) -> usize { match n { 0 => a, 1 => b, _ => f(n - 1, b, a + b), } } f(n, 0, 1) } const F77: usize = fibonacci(77);
535 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 15:36:32.04 ID:glYADNck.net] >>511 俺環の遅いマシンだと6倍近く速くなった この差なら用途によっては汚くする価値が十分あるね まあ実際のプログラムでBigUintのサイズまで一つ一つイテレータで返すような使い方をすることはまずないだろうけど
536 名前:デフォルトの名無しさん [2022/06/07(火) 15:42:23.15 ID:fRg0KLfu.net] >>511 コードが汚い上にget_mutが失敗してpanicする欠陥コードを恥ずかしげもなく披露できるもんだな
537 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 17:49:46.06 ID:jaUMaLrL.net] >>525 だからそう言ってる、そして機能紹介は知ってることを言わなくてよいよ?コンパイル時実行とは違う。gcc系は数学的に既に答えが出るようなアルゴリズムを書いた場合に演算しないで低い桁で答えを持つ場合がある。 意味が分からないんだったら日本語から勉強しなおせ。それと汚いものを張り付けるな
538 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 18:06:57.96 ID:WAenZnu4.net] >>523 定数たたみ込みのことかな 試した限りでは gcc でも clang でも rustc でも最適化されて fib 呼び出しは消えているよ どういうコードで問題おきるの? gcc: https://godbolt.org/z/nx3hnsxTT clang: https://godbolt.org/z/MYc7G9jeG rustc: https://godbolt.org/z/x18ob3MjP
539 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 18:10:22.54 ID:WAenZnu4.net] >>523 あとrustがllvmに執着しているというのも間違いで gccのcodegenを使えるようにするプロジェクトもあって活発に開発されてるよ https://github.com/rust-lang/rustc_codegen_gcc
540 名前:デフォルトの名無しさん [2022/06/07(火) 18:17:47.44 ID:1EdYDqGn.net] >>524 >>620 よろすく
541 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 20:22:53.88 ID:UaJ7fd+W.net] フィボナッチなんて普通に解析解あるんだからそれ使えばいいじゃん
542 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 20:28:59.38 ID:ZSCymycr.net] フィボナッチよりボイニッチを解読してくれ
543 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 23:19:58.58 ID:bfW1tdFv.net] ボイニッチはどうせ創作ノートでしかないし
544 名前:デフォルトの名無しさん [2022/06/07(火) 23:25:02.45 ID:lnwubCy8.net] >>532 フィボナッチは単なる題材に過ぎないことを理解できていないのはヤバいぞ 例えば>>529 の定数畳み込みや>>502 のジェネリックやOptionが最適化される話などが本題 単純だが単純過ぎない題材の例としてたまたまフィボナッチ数列が使われている
545 名前:デフォルトの名無しさん mailto:sage [2022/06/07(火) 23:57:19.63 ID:YQOkxy3N.net] ワッチョイありスレに移住してここは複おじに明け渡してやったほうがいいのかもな
546 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 00:55:31.29 ID:QhxBwpDW.net] >>536 複おじの意味がいまだにわからないが ジェネリックよりも速いコードがあるならきちんと示そうぜ >>506 はイテレータと関数の異種比較のイカサマ >>511 はイテレータ同士の比較へ改善されたがイテレータの中のunwrapでpanicするマガイモノ そんなデタラメばかりしていたら信頼を失うぜ
547 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 01:35:00.04 ID:jyTDsLRS.net] >>537 >>481 は?
548 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 01:40:47.24 ID:C5b6ywPX.net] 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
549 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 02:05:38.58 ID:jyTDsLRS.net] >>539 はin-placeなchecked_addを実現するtraitがないことで速度差大きくなってるものだよね ジェネリクスが遅いと言ったときに、 ジェネリクスの機構自体による速度差と、ジェネリクスにまつわるエコシステムによる速度差という二通りの解釈があると思うけど、 >>537 は前者のことを、>>539 は後者のことを言っていて議論がかみ合っていないのではないか ジェネリクスの機構だけの話をするなら前者の議論だけで良いけど、 メンテナンスコスト含めた実用性考えると後者の範囲も考える必要があるよね、 というのが>>514 で言いたかったこと
550 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 02:17:57.20 ID:aUi5KtMm.net] >>539 君のベンチはいつも何と何の違いを比較しようとしているのかよくわからない 一方で>>502 は何と何を比較するのかを明確にした上で各項目毎に段階を経て比較しているから 仮にベンチで違いがあればその要因が明確となり知見が得られる比較となっている 君の投稿からは結果に対して何が要因なのか知見が全く得られない
551 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 02:29:17.13 ID:aUi5KtMm.net] >>540 まず速度差がそのおっしゃっているchecked_addによるものなのかどうかを明確にしたほうが良いかと思う >>502 を見てみると(2)→(3)がchecked_addの有無になっているがベンチは同じ その結果からchecked_addは関係ないのではないか?
552 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 04:21:09 ID:uEpi8n1p.net] >>540 ジェネリックにやりたいならCheckedAddAssignを作ればいいんじゃん? Rcのもジェネリックにもできるわけだし
553 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 05:52:38 ID:78wIRTgY.net] >>540 そもそもコードが汚いという指摘が発端なので 前者が論点だと思ってる人はいないと思うよ
554 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 06:22:34.20 ID:2tL4qRNc.net] >>544 元と同一コードを含む5種類のベンチ>>502 のコードを見たけど 特に汚いコードは見当たらないんじゃない? もしあるならば具体的にどの部分なのかを言ったほうがいいと思うよ
555 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 08:45:07.60 ID:C5b6ywPX.net] >>541 「checked_addしてから代入」と「add_assign」の比較だよ で現状後者はジェネリックにやるために適切なtraitが無いから、 ジェネリックな関数では性能向上に限界があるよねって話 >>540 の言う通り、ジェネリック関数とmonomorphized関数をの性能を比較したいわけじゃないよ >>542 >>490 ,491でも出た通り、checked_addとadd(両辺とも参照の場合)はどっちもcloneが発生する だから(2)を(3)にしても、遅いchecked_addを遅いaddで置き換えただけなので性能向上は無い あとclone発生してるのはここね、docs.rsの[src]からたどれば&BigUint同士のaddがこのマクロで定義されているのが分かるはず https://docs.rs/num-bigint/latest/src/num_bigint/macros.rs.html#91-107
556 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 09:03:01.17 ID:C5b6ywPX.net] あんまり頑固になっても聞かなさそうなんでそろそろ妥協案でも どうしてもジェネリックでやりたかったら、num::PrimIntでも使ってればここまでの批判は無かったんじゃないですかね BigUint/BigIntは範囲から外れるけど、それはやっぱりそういうものなんですよ
557 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 09:13:21.45 ID:2tL4qRNc.net] >>546 あなたのコード>>539 もclone()しているから 1回あたりclone()が1回発生している点で同じではないかね そこは重要なところだから曖昧な推測で済ませずに細かい差異でベンチマークを取ったほうがいいのではないか
558 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 11:26:56.36 ID:oyhrGaRU.net] Rustが自由自在に書けるようなプログラマになりたがったンゴねえ ワイは低脳だから躓いてるンゴ 例えば&'static TとT: 'staticの違いがなんかあるらしいんやがわからなかったンゴ 前者はプログラム終了時まで生きる変数の参照って意味で後者はもしTに参照があったらそれは'static以上生きるって解釈であってるんか?
559 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 11:49:32.36 ID:oyhrGaRU.net] いや理解したんご 前者は参照型しか受け付けないけど後者はそれ以上の種類の型を受け付けるンゴねえ さらに違いがあるかもだけど勉強進めるわ なんでもなかった
560 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 12:37:42.94 ID:C5b6ywPX.net] >>548 そのベンチが>>539 のつもりなんだけど、これにどういう問題があって具体的には何をしろと? from_fn使ってる分(5)のほうが近いから比較対象を(1)から(5)に変えろってこと? というかそれが分かっているなら他人にやらせるんでなく自分で検証すればいいのでは?
561 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 14:46:42.18 ID:JNpA1ROM.net] >>551 結局、何が原因なん? ジェネリック?それともchecked_add?あるいは変数Some?まさかのswap? Rustスレとしてはコードよりも原因を知りたい
562 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 15:00:02.66 ID:0R8j40RZ.net] >>502 「1.5倍も差があるのは妙だな Rustでは最適化されるのでジェネリックで書こうがそんな差は出ないはず」 これがそもそもおかしい、最適化されようが何だろうが生成されるコードは違うのでMIRなりdisamなりでインストラクション単位で目視すれば一発だろ。ベンチを取る以前の思い込み低レベルな話 そしてほぼ最適化された無駄のないコードだったとしても >>523 ここ5年程度のCPUでは64バイトのDSB境界を持つ小さなループ呼び出しなどが単一のμopsキャッシュに収まる場合があるがコードの配置によって異なり1.5倍程度の差が出ても不思議じゃない。 言ってるのに全く聞かない
563 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 15:48:23.76 ID:kiLfNcoT.net] >>553 その件は1.5倍差あった>>481 がイテレータと関数を比較するという大チョンボをしていたことが原因と判明済 そしてジェネリックか否か自体では速度に差が出ないことを>>502 のベンチが証明済
564 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 17:10:39.22 ID:C5b6ywPX.net] >>554 よく見ろ、それは>>475 の話だ >>481 は両方とも(usize) -> BigUintな関数
565 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 17:16:08.77 ID:LlAtoLIj.net] これだけ時間をか
566 名前:けても原因すら分からずノンジェネリックとの速度差を埋められない状況をコストとして認識できてないのが恐ろしい [] [ここ壊れてます]
567 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 17:31:51.50 ID:H0oyRmek.net] 一般的に、数列を順に求めるイテレータと、 そのうちの特定の数だけを求める関数とでは、 オーダー問題もアルゴリズムも変わってくるため、 >>481 はまた別の問題となっている。 イテレータ同士の比較で1.5倍となっていないことからも、 異なる問題であると理解できるはず。 >>556 ジェネリックとノンジェネリックに速度差が無いことは、 >>502 で既に示されたのだから、 ジェネリックかどうかは一切関係ないと思う。 ジェネリックとは別の問題。
568 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 18:18:03.20 ID:cKPONsWM.net] >>557 >>502 はジェネリックでも実現できるコードをノンジェネリックにしただけ ノンジェネリックならadd_assign, mem::swap, cloneで>>502 のいずれよりも速いコードが書けるが ジェネリックだとchecked_addを使わざるを得ず同じことが実現できない
569 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 18:32:47.55 ID:y1p7Fxu2.net] >>537 では「ジェネリックよりも速いコードがあるならきちんと示そうぜ」と言っていて >>540 の言う違いを理解している感じだったのに いざ本当にコードが出てくるとジェネリクス自体のオーバーヘッドの話に限定して、差は無いと連呼 わざとやってんの?
570 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 19:11:11 ID:sj9oTS9C.net] >>558 > ジェネリックだとchecked_addを使わざるを得ず同じことが実現できない それは違うのではないか? ジェネリックでも自由にCheckedAddAssign等を定義して実現することが可能という話が既に出ている >>492 >>543 一方でノンジェネリックで書いてもオーバフロー対策としてchecked_addは使わざるを得ない つまりどちらが有利とか優れているとかいう問題ではない
571 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 19:45:52.60 ID:btlg3B6B.net] >>560 他人の意見を鵜呑みにしてないでやってみれば? 俺はちょっと試してみたけど結局無理だと確信したよ
572 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 19:54:30.37 ID:hF0KVPZD.net] CheckedAddAssignの定義難しいよね cloneを減らせるうまい定義見せて欲しい
573 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 19:58:01.42 ID:hF0KVPZD.net] >>560 > 一方でノンジェネリックで書いてもオーバフロー対策としてchecked_addは使わざるを得ない つまりどちらが有利とか優れているとかいう問題ではない BigUintの場合はオーバーフローを想定しなくて良いからただのAddAssignで良いよね ジェネリックな実装の場合は考慮すべき事項が増えるというハンデを抱えている
574 名前:デフォルトの名無しさん mailto:sage [2022/06/08(水) 20:09:35.76 ID:Pauu0yN9.net] 基地同士の喧嘩おもすれー