公式
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/
Rust part15
■ このスレッドは過去ログ倉庫に格納されています
2022/05/12(木) 18:28:20.99ID:cuIcFT6k
417デフォルトの名無しさん
2022/05/31(火) 10:19:23.69ID:aYJaA5wp418デフォルトの名無しさん
2022/05/31(火) 14:58:10.34ID:qkI00F5r419デフォルトの名無しさん
2022/05/31(火) 20:23:20.27ID:/PJVfDdU env feature指定すると扱える
あと今時の形式>>416ではderive featureも必須
あと今時の形式>>416ではderive featureも必須
420デフォルトの名無しさん
2022/05/31(火) 21:26:01.43ID:bCRscqs9421デフォルトの名無しさん
2022/06/03(金) 21:24:55.91ID:3LVnIAMZ 配列の中で移動コピーする方法を教えてください
例えば
移動前 [X, X, X, X, 4, 5, 6, 7, 8, 9]
移動後 [4, 5, 6, 7, 8, 9, X, X, X, X];
Xは任意の値で構わないです
可能ならばstable safeでお願いします
例えば
移動前 [X, X, X, X, 4, 5, 6, 7, 8, 9]
移動後 [4, 5, 6, 7, 8, 9, X, X, X, X];
Xは任意の値で構わないです
可能ならばstable safeでお願いします
422デフォルトの名無しさん
2022/06/03(金) 21:51:48.48ID:zWyAdBA8 複おじか?お前
423デフォルトの名無しさん
2022/06/03(金) 21:58:58.40ID:58QZIwzn >>421
xs.rotate_left(4);
xs.rotate_left(4);
424デフォルトの名無しさん
2022/06/03(金) 22:49:16.06ID:/2hdnJHh コピーとあるからcopy_within(4.., 0)でいいんじゃないか
rotate_leftだと大きな配列で後方と前方の間の小さいサイズのコピーでも全体のコピーが発生して無駄
rotate_leftだと大きな配列で後方と前方の間の小さいサイズのコピーでも全体のコピーが発生して無駄
425デフォルトの名無しさん
2022/06/03(金) 23:22:12.53ID:58QZIwzn なるほど、任意の値で構わないってのはそういうことだったのか
426デフォルトの名無しさん
2022/06/03(金) 23:55:24.30ID:3LVnIAMZ ありがとうございました
ところで文字列にはfindメソッドがあって便利なのですが
指定した値が配列の中で前から何番目にあるかを返すメソッドはありますか?
ところで文字列にはfindメソッドがあって便利なのですが
指定した値が配列の中で前から何番目にあるかを返すメソッドはありますか?
427デフォルトの名無しさん
2022/06/04(土) 00:13:56.42ID:1UnvA590 >>426
slice::iter::position
slice::iter::position
428デフォルトの名無しさん
2022/06/04(土) 00:40:32.70ID:oXzC1k// positionでもfindでも行ける
let buf = b"abc\ndef\n";
assert_eq!(Some(3), buf.iter().position(|&b| b == b'\n'));
assert_eq!(Some(3), (0..buf.len()).find(|&i| buf[i] == b'\n'));
文字列でのこの簡潔さと比べるとスライス直結findが欲しくなるのはわかる
let str = "abc\ndef\n";
assert_eq!(Some(3), str.find('\n'));
let buf = b"abc\ndef\n";
assert_eq!(Some(3), buf.iter().position(|&b| b == b'\n'));
assert_eq!(Some(3), (0..buf.len()).find(|&i| buf[i] == b'\n'));
文字列でのこの簡潔さと比べるとスライス直結findが欲しくなるのはわかる
let str = "abc\ndef\n";
assert_eq!(Some(3), str.find('\n'));
429デフォルトの名無しさん
2022/06/04(土) 00:48:39.66ID:SnRPHFsS bikeshed
430デフォルトの名無しさん
2022/06/04(土) 01:04:34.73ID:oXzC1k// str::findは部分列も対応
let str = "abc\r\ndef\r\n";
assert_eq!(Some(3), str.find("\r\n"));
なぜslice::findを作らなかったのだろう?
let str = "abc\r\ndef\r\n";
assert_eq!(Some(3), str.find("\r\n"));
なぜslice::findを作らなかったのだろう?
431デフォルトの名無しさん
2022/06/04(土) 09:04:26.92ID:LG8suQe9 出た
汚コード
汚コード
432デフォルトの名無しさん
2022/06/04(土) 09:19:04.11ID:UQf/W43E Rustの仕様自体が汚いんだよ
433デフォルトの名無しさん
2022/06/04(土) 09:34:38.78ID:nKFWMn7j 汚コードでもいいやん
反面教師になるんだから
ただし単発の短いコードに限る
フィボナッチ汚コードのペタペタ連投みたいなのはもう勘弁
反面教師になるんだから
ただし単発の短いコードに限る
フィボナッチ汚コードのペタペタ連投みたいなのはもう勘弁
434デフォルトの名無しさん
2022/06/04(土) 09:56:15.67ID:kJkfvymC 汚コードなの?初心者だからマジわからん
docのstd::slice::iter::position をみたら似たようなコードだったけど
docのstd::slice::iter::position をみたら似たようなコードだったけど
435デフォルトの名無しさん
2022/06/04(土) 10:11:21.31ID:SnRPHFsS >>430
sliceから部分sliceを探索する頻度が文字列から部分文字列を探索する頻度に比べて圧倒的に低いから、じゃないの
C++のSTLも文字列にしかメンバ関数としてのfindは無いし、これも同じ理由ではないかな
sliceから部分sliceを探索する頻度が文字列から部分文字列を探索する頻度に比べて圧倒的に低いから、じゃないの
C++のSTLも文字列にしかメンバ関数としてのfindは無いし、これも同じ理由ではないかな
436デフォルトの名無しさん
2022/06/04(土) 11:23:20.02ID:HjDRTZ3n Rustのエラー表示すばらしいなほんとに
めちゃくちゃ楽だわな
めちゃくちゃ楽だわな
437デフォルトの名無しさん
2022/06/04(土) 12:01:38.84ID:K/Ra00gu いつも汚コード言ってるやつはキチガイだから無視しとけ
>>430
部分スライスに対してもiterの代わりにwindowsを使えば同じようにpositionで部分文字列findと同じ結果を得られる
let buf = b"abc\r\ndef\r\n";
assert_eq!(Some(3), buf.windows(2).position(|b| b == b"\r\n"));
>>430
部分スライスに対してもiterの代わりにwindowsを使えば同じようにpositionで部分文字列findと同じ結果を得られる
let buf = b"abc\r\ndef\r\n";
assert_eq!(Some(3), buf.windows(2).position(|b| b == b"\r\n"));
438デフォルトの名無しさん
2022/06/04(土) 12:02:08.90ID:rPOcVTB8 エラー表示が出ている時点で(ry
439デフォルトの名無しさん
2022/06/04(土) 12:43:02.16ID:SnRPHFsS bikeshed bikeshed bikeshed
440デフォルトの名無しさん
2022/06/04(土) 13:12:11.67ID:sY7vYVfw 文字列のPatternに相当するものがsliceになないからでは
441デフォルトの名無しさん
2022/06/04(土) 13:40:33.24ID:NhLlWR3w442デフォルトの名無しさん
2022/06/04(土) 13:47:22.44ID:DNUj2Sn5 汚コード公式汚コードですわ~!
443デフォルトの名無しさん
2022/06/04(土) 13:57:36.96ID:nieqt9o7444デフォルトの名無しさん
2022/06/04(土) 14:11:57.60ID:QZjOvH6O こんなスレに質問しに来る初学者なんてものは最初から存在しないんだろうな
445デフォルトの名無しさん
2022/06/04(土) 14:23:56.41ID:ThNWOKir ん?
「初心者だからわからん」というのが汚コーダーの自演だろってこと?
「初心者だからわからん」というのが汚コーダーの自演だろってこと?
446デフォルトの名無しさん
2022/06/04(土) 14:34:25.51ID:QAuL8N6o そうだよ
447デフォルトの名無しさん
2022/06/04(土) 14:39:18.00ID:xn39310Q 複クンはね
みんなに見てもらいたいんよ
つきあってあげてよ
みんなに見てもらいたいんよ
つきあってあげてよ
448デフォルトの名無しさん
2022/06/04(土) 15:03:39.84ID:Skn9YyLT449434
2022/06/04(土) 15:21:18.99ID:kJkfvymC 自演臭くなるからアレなんだけど
暇潰しに公式ドキュメントと照らし合わせて疑問に思ったから書き込んだだけで
ただの通りすがりだからね
暇潰しに公式ドキュメントと照らし合わせて疑問に思ったから書き込んだだけで
ただの通りすがりだからね
450デフォルトの名無しさん
2022/06/04(土) 15:39:42.64ID:nieqt9o7451デフォルトの名無しさん
2022/06/04(土) 16:10:13.56ID:VXQtFnUU 書いてあるコードよりましなコードを出せずに汚コードって呟くしかない可哀想な人は暖かくスルーしてやってくださいな
452デフォルトの名無しさん
2022/06/04(土) 16:13:38.80ID:jusi9BoA453デフォルトの名無しさん
2022/06/04(土) 16:30:17.39ID:43LVHAPc454デフォルトの名無しさん
2022/06/04(土) 21:35:57.57ID:Tzl373uA うわーこれ確定じゃん
複くんRustなんかやめてネトサポやれば?
複くんRustなんかやめてネトサポやれば?
455デフォルトの名無しさん
2022/06/04(土) 23:04:11.48ID:FBgyqIef >フルボッコにされて撃沈。
主砲「Copyはディープで高コストだから避けるべき」発射! ==> ドッカーンwww撃沈www
主砲「Copyはディープで高コストだから避けるべき」発射! ==> ドッカーンwww撃沈www
456デフォルトの名無しさん
2022/06/04(土) 23:12:57.28ID:DCKDFwmc 真面目に書いとくとusizeみたいな数値プリミティブの場合はCopy前提で全く問題ないよ
気になる人はベンチにかけてね
気になる人はベンチにかけてね
457デフォルトの名無しさん
2022/06/04(土) 23:38:03.39ID:UrkwxQuP458デフォルトの名無しさん
2022/06/04(土) 23:52:08.43ID:W82CC99g 汚コード連呼厨は信頼できない
代わりのコードをいつも出せない
珍しく出してきたら元より劣化してた
代わりのコードをいつも出せない
珍しく出してきたら元より劣化してた
459デフォルトの名無しさん
2022/06/04(土) 23:57:58.57ID:SnRPHFsS460デフォルトの名無しさん
2022/06/05(日) 00:16:50.25ID:Y4E70HYz 毎週This Week in Rustのリンクでも貼ればこのくだらない流れは終わるのだろうか
461デフォルトの名無しさん
2022/06/05(日) 00:46:34.90ID:9LpkJgbZ ところでスライスへのfindメソッドなどの後付けはRustのorphan ruleを犯さずに可能なの?
462デフォルトの名無しさん
2022/06/05(日) 04:00:56.97ID:4HXc2Nfq trait定義すればできる
463デフォルトの名無しさん
2022/06/05(日) 09:25:11.96ID:Zl7Pb69A > 誰も求めてないfindで書き直したり
そもそも、誰ももとめてない
「ぼくのかんがえたさいきょうふぃぼなっちいてれーた」
をどんだけ貼り付けたんだろうな彼はw
誰も求めてないものを必死でシコってるからうんざりなんよ
そもそも、誰ももとめてない
「ぼくのかんがえたさいきょうふぃぼなっちいてれーた」
をどんだけ貼り付けたんだろうな彼はw
誰も求めてないものを必死でシコってるからうんざりなんよ
464デフォルトの名無しさん
2022/06/05(日) 10:25:57.06ID:yQi6baxx 複クンはなぜ汚いと言われるのか理解しないね
言語やライブラリの制約で避けられないような汚なさならここまで言われない
言語やライブラリの制約で避けられないような汚なさならここまで言われない
465デフォルトの名無しさん
2022/06/05(日) 10:34:37.11ID:g2kCstof シンプルに意図が伝わりやすい書き方が他にあっても
ぼくのかんがえたさいきょうのシコシココードを我慢出来ずに開陳しちゃうからここが汚部屋になる
ぼくのかんがえたさいきょうのシコシココードを我慢出来ずに開陳しちゃうからここが汚部屋になる
466デフォルトの名無しさん
2022/06/05(日) 10:48:55.83ID:REWyb6H9467デフォルトの名無しさん
2022/06/05(日) 10:54:21.85ID:ULNisafI468デフォルトの名無しさん
2022/06/05(日) 14:57:13.62ID:1ZIcYX0i469デフォルトの名無しさん
2022/06/05(日) 17:36:49.26ID:kdHlti+w470デフォルトの名無しさん
2022/06/05(日) 17:53:32.33ID:uQ7Of1B3471デフォルトの名無しさん
2022/06/05(日) 18:25:46.65ID:Zl7Pb69A まーたふぃぼなっち言ってるw
バカのひとつ覚えすなあw
バカのひとつ覚えすなあw
472デフォルトの名無しさん
2022/06/05(日) 18:50:30.04ID:1ZIcYX0i473デフォルトの名無しさん
2022/06/05(日) 21:53:01.43ID:ZauVJiyh >>470
何のメリットもなく汚くしてるだけだから受け入れられないという話だったんだが
何のメリットもなく汚くしてるだけだから受け入れられないという話だったんだが
474デフォルトの名無しさん
2022/06/05(日) 22:11:06.61ID:ZR9IOkh3 ジェネリックのフィボナッチや
ジェネリックのカウントアップみたいな
架空のユースケースの話題はもういいよ
ジェネリックのカウントアップみたいな
架空のユースケースの話題はもういいよ
475デフォルトの名無しさん
2022/06/05(日) 22:14:01.51ID:uQ7Of1B3 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でもベンチマークできればいいのになあ
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でもベンチマークできればいいのになあ
476デフォルトの名無しさん
2022/06/05(日) 22:14:34.17ID:IymwRCap 「RustとC++を学ぼうと思ってるプログラミング初心者です。」(架空)
477デフォルトの名無しさん
2022/06/05(日) 22:24:27.68ID:+fEwSMrP どの場でも同じだが
「技術的な話題と技術的な指摘」
「他者の話題と他者への攻撃」
この違いがわからず後者を行なうダメ人間のせいで場が荒れる
「技術的な話題と技術的な指摘」
「他者の話題と他者への攻撃」
この違いがわからず後者を行なうダメ人間のせいで場が荒れる
478デフォルトの名無しさん
2022/06/05(日) 22:25:12.37ID:xgxgbUCt479デフォルトの名無しさん
2022/06/05(日) 22:36:45.16ID:4HXc2Nfq >>475
playgroundみたいな環境でベンチマークやれたとしても結果が安定しないのでは
playgroundみたいな環境でベンチマークやれたとしても結果が安定しないのでは
480デフォルトの名無しさん
2022/06/05(日) 22:40:18.97ID:+fEwSMrP >>475
純粋にジェネリックか否かの比較をしたいならばadd_assignとaddの違いなども含めて条件を全て揃えたほうがよい
元がiter::successorsを使っているならば非ジェネリック版も同じくそれで揃えてみてはどうか
純粋にジェネリックか否かの比較をしたいならばadd_assignとaddの違いなども含めて条件を全て揃えたほうがよい
元がiter::successorsを使っているならば非ジェネリック版も同じくそれで揃えてみてはどうか
481デフォルトの名無しさん
2022/06/05(日) 23:17:38.06ID:uQ7Of1B3 >>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]
>>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]
482デフォルトの名無しさん
2022/06/05(日) 23:34:45.61ID:MGWqyCtZ483デフォルトの名無しさん
2022/06/06(月) 00:32:35.96ID:m7d3UK5s イテレータで計測してみたけど
>>295のoption::takeだとcloneしても速度変わらないな
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=283e5cd13159cab00fcc68d56952df01
>>295のoption::takeだとcloneしても速度変わらないな
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=283e5cd13159cab00fcc68d56952df01
484デフォルトの名無しさん
2022/06/06(月) 02:33:06.91ID:ETmHHhEk >>483
そういう比較はそれ以外の部分のコードを揃えないと何が要因なのか判断できないよ
そういう比較はそれ以外の部分のコードを揃えないと何が要因なのか判断できないよ
485デフォルトの名無しさん
2022/06/06(月) 03:21:12.98ID:CfMv9iPR Rustってフィボナッチ専用言語みたいだな
486デフォルトの名無しさん
2022/06/06(月) 12:48:39.09ID:fwdLGVHm487デフォルトの名無しさん
2022/06/06(月) 14:47:49.79ID:bWO8YoN9 premature optimizationとpremature abstructionの典型例
・具体的なユースケースを想定しない
・トレードオフを考えない
・誰も求めてない抽象化
・計測を伴わない思い込み最適化
コードの汚さと悉く間違った主張の根っこは同じ
・具体的なユースケースを想定しない
・トレードオフを考えない
・誰も求めてない抽象化
・計測を伴わない思い込み最適化
コードの汚さと悉く間違った主張の根っこは同じ
488デフォルトの名無しさん
2022/06/06(月) 15:32:14.02ID:eTH/ySe7 複オジのおかげでいろんな教訓が再認識できて良かったね
反面教師の鑑
めでたしめでたし
反面教師の鑑
めでたしめでたし
489デフォルトの名無しさん
2022/06/06(月) 15:53:42.58ID:c+f9iTO8490481
2022/06/06(月) 16:16:13.39ID:lWIakgkT >>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++で二項演算子をオーバーロードするときのイディオムです
これを思い出しながら書きました
正確に言えば
問題は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++で二項演算子をオーバーロードするときのイディオムです
これを思い出しながら書きました
491デフォルトの名無しさん
2022/06/06(月) 16:52:12.73ID:yU0i67fk >>490
ソース見るところ勘違いしてた
確かにaddでも&self使えばclone入るからchecked_add並みに遅くなった
checked_addにownedのselfを取るバージョンが追加されれば改善するだろうけど
trait定義からして対応するつもりのないユースケースかもね
ソース見るところ勘違いしてた
確かにaddでも&self使えばclone入るからchecked_add並みに遅くなった
checked_addにownedのselfを取るバージョンが追加されれば改善するだろうけど
trait定義からして対応するつもりのないユースケースかもね
492デフォルトの名無しさん
2022/06/06(月) 16:57:14.59ID:+9236oDl >>491
CheckedAddAssignを導入すれば全て解決しそうだな
CheckedAddAssignを導入すれば全て解決しそうだな
493デフォルトの名無しさん
2022/06/06(月) 17:23:25.42ID:V1HrdzSd 必要ならextension traitを書けばいい
そこまでしてジェネリックにする価値があるとは思えないけど
そこまでしてジェネリックにする価値があるとは思えないけど
494デフォルトの名無しさん
2022/06/06(月) 18:19:44.52ID:fWB2qr5d リーナスさんから受けたパニックのありがたい指摘って結局どうなったん?
495デフォルトの名無しさん
2022/06/06(月) 20:58:23.31ID:gJyU9Hxy 放置されてんじゃないの?
コンパイラがパニック起こさないように変えられたって聞かないし
コンパイラがパニック起こさないように変えられたって聞かないし
496デフォルトの名無しさん
2022/06/06(月) 21:04:20.00ID:fWB2qr5d パニックにならないオプションくらい作ってもいい気もするけどね
497デフォルトの名無しさん
2022/06/06(月) 21:29:53.43ID:qARo1+y7 パニック自体はもう1年前くらいに修正済み
今はv7 patchまで来ていて大きな懸念も出ていないから
そろそろマージされてもおかしくはない
今はv7 patchまで来ていて大きな懸念も出ていないから
そろそろマージされてもおかしくはない
498デフォルトの名無しさん
2022/06/06(月) 21:51:13.91ID:gJyU9Hxy リーナスレベルに行く前に誰も問題視してなくて指摘もされてないんだろうか
みんなガバガバなんだな
panic前提のコーディング
みんなガバガバなんだな
panic前提のコーディング
499デフォルトの名無しさん
2022/06/06(月) 22:44:51.98ID:Yvz8OCum try_reserveはstabilizeされてるよ
500デフォルトの名無しさん
2022/06/06(月) 23:01:32.72ID:aWO23bGN501デフォルトの名無しさん
2022/06/06(月) 23:06:15.51ID:2Zdu7NAR ジェネリックフィボナッチと同程度にどうでもいい
502デフォルトの名無しさん
2022/06/06(月) 23:15:40.43ID: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のジェネリックコードで問題なし、となる
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のジェネリックコードで問題なし、となる
503デフォルトの名無しさん
2022/06/06(月) 23:58:37.28ID:hMQAMrNY504デフォルトの名無しさん
2022/06/07(火) 00:13:51.07ID:GvuMwmTL505デフォルトの名無しさん
2022/06/07(火) 00:16:51.98ID:y2mAB4fu506デフォルトの名無しさん
2022/06/07(火) 00:17:18.96ID:YQOkxy3N 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 の使い方が分からなかったのかな
test bench_1 ... bench: 426,714 ns/iter (+/- 5,563)
test bench_fast ... bench: 201,510 ns/iter (+/- 2,926)
Criterion の使い方が分からなかったのかな
507デフォルトの名無しさん
2022/06/07(火) 00:19:44.22ID:y2mAB4fu508デフォルトの名無しさん
2022/06/07(火) 00:35:03.04ID:z0w37Unr509デフォルトの名無しさん
2022/06/07(火) 00:38:00.86ID:wvlfxzyf まーたすがすがしいまでの自演だなぁ
510デフォルトの名無しさん
2022/06/07(火) 00:39:26.17ID:r6MnfEMB511デフォルトの名無しさん
2022/06/07(火) 01:10:53.92ID:YQOkxy3N 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)
こんな汚ないことしてまでイテレータになんかしたくないんだけど
どうせ次の文句も大体予想付くし
test bench_1 ... bench: 420,671 ns/iter (+/- 53,102)
test bench_fast ... bench: 219,091 ns/iter (+/- 1,147)
こんな汚ないことしてまでイテレータになんかしたくないんだけど
どうせ次の文句も大体予想付くし
512デフォルトの名無しさん
2022/06/07(火) 01:35:52.48ID:gaZATsj9 この件はRustにとって重要なことだから口を挟むが、
Rustではジェネリックで書いてもmonomorphizationによって各型で書いた時と同じコードになる。
だから標準ライブラリの大半はジェネリックに書かれている。
そしてSomeなどのOptionは最適化できる時は綺麗に消えるため、
BigIntのchecked_addのように常にSomeを返す時も最適化でOptionは消えると考えられる。
いずれも抽象的に書けるのに動かすとC並に速いというRustの長所である。
つまり、>>502の結果が出たことはそれらが実証付けられたことになる。
しかし、以前からジェネリックは無駄とか遅いとかRustの長所に反する主張をする人がいるので気になっていた。
今回もRustのジェネリックは遅いと主張するために、
>>506のように、完全に異なるもの同士を比較したり、
>>511のように、Rcを返すという別仕様のものにしてまで、ジェネリックは遅いと主張し出した。
反Rustか反ジェネリックの立場なのかもしれないが、そういう捏造や詐欺のようなことはよくない。
Rustではジェネリックで書いてもmonomorphizationによって各型で書いた時と同じコードになる。
だから標準ライブラリの大半はジェネリックに書かれている。
そしてSomeなどのOptionは最適化できる時は綺麗に消えるため、
BigIntのchecked_addのように常にSomeを返す時も最適化でOptionは消えると考えられる。
いずれも抽象的に書けるのに動かすとC並に速いというRustの長所である。
つまり、>>502の結果が出たことはそれらが実証付けられたことになる。
しかし、以前からジェネリックは無駄とか遅いとかRustの長所に反する主張をする人がいるので気になっていた。
今回もRustのジェネリックは遅いと主張するために、
>>506のように、完全に異なるもの同士を比較したり、
>>511のように、Rcを返すという別仕様のものにしてまで、ジェネリックは遅いと主張し出した。
反Rustか反ジェネリックの立場なのかもしれないが、そういう捏造や詐欺のようなことはよくない。
513デフォルトの名無しさん
2022/06/07(火) 01:49:10.77ID:eprvoL3W >>512
同意
同意
514デフォルトの名無しさん
2022/06/07(火) 03:36:34.68ID:hBVbMSyF >>512
ジェネリクスが無駄だの遅いだのはコード生成の話ではなくてコードのメンテナンスコスト含めた全体の話では
例えば今回ジェネリックなコードで無駄なcloneを避けるためには CheckedAddAssign といった trait を用意し、各整数型に実装するという余計な手間が発生する
また、各整数に追加のtraitを実装したとしても固定長の整数型ではすぐに桁あふれしてしまうから、実質BigUintの実装しか意味がないものになる
だったら最初からジェネリックにせずBigUintで実装するか、BigUintやBigIntといった桁あふれしない型だけを対象にすればよい
ジェネリクスの良さを語りたいならもっと良い例があるんじゃないの
ジェネリクスが無駄だの遅いだのはコード生成の話ではなくてコードのメンテナンスコスト含めた全体の話では
例えば今回ジェネリックなコードで無駄なcloneを避けるためには CheckedAddAssign といった trait を用意し、各整数型に実装するという余計な手間が発生する
また、各整数に追加のtraitを実装したとしても固定長の整数型ではすぐに桁あふれしてしまうから、実質BigUintの実装しか意味がないものになる
だったら最初からジェネリックにせずBigUintで実装するか、BigUintやBigIntといった桁あふれしない型だけを対象にすればよい
ジェネリクスの良さを語りたいならもっと良い例があるんじゃないの
515デフォルトの名無しさん
2022/06/07(火) 07:03:55.78ID:/+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を使うまでもない需要も多いのだからジェネリックに書かれたコード一つで十分と感じる
そのコードはイテレータ内部で無理に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を使うまでもない需要も多いのだからジェネリックに書かれたコード一つで十分と感じる
516デフォルトの名無しさん
2022/06/07(火) 08:13:15.84ID:AZaNrbV3■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【サッカー】U-17日本代表、激闘PK戦制す 北朝鮮撃破で6大会ぶり8強入り U17W杯 [久太郎★]
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★3 [ぐれ★]
- 【芸能】日中関係悪化でエンタメ業界に大ダメージ… JO1の中国でのイベント中止、邦画は公開延期、STARTOアイドルへの影響も [冬月記者★]
- XやChatGPTで広範囲の通信障害 投稿や閲覧できず [蚤の市★]
- 現役猟師・東出昌大、クマ被害続出も過熱する報道に「クマはそんな危ないもんじゃない」理由語る [muffin★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
