公式
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
545デフォルトの名無しさん
2022/06/08(水) 06:22:34.20ID:2tL4qRNc546デフォルトの名無しさん
2022/06/08(水) 08:45:07.60ID:C5b6ywPX >>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
「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
547デフォルトの名無しさん
2022/06/08(水) 09:03:01.17ID:C5b6ywPX あんまり頑固になっても聞かなさそうなんでそろそろ妥協案でも
どうしてもジェネリックでやりたかったら、num::PrimIntでも使ってればここまでの批判は無かったんじゃないですかね
BigUint/BigIntは範囲から外れるけど、それはやっぱりそういうものなんですよ
どうしてもジェネリックでやりたかったら、num::PrimIntでも使ってればここまでの批判は無かったんじゃないですかね
BigUint/BigIntは範囲から外れるけど、それはやっぱりそういうものなんですよ
548デフォルトの名無しさん
2022/06/08(水) 09:13:21.45ID:2tL4qRNc549デフォルトの名無しさん
2022/06/08(水) 11:26:56.36ID:oyhrGaRU Rustが自由自在に書けるようなプログラマになりたがったンゴねえ
ワイは低脳だから躓いてるンゴ
例えば&'static TとT: 'staticの違いがなんかあるらしいんやがわからなかったンゴ
前者はプログラム終了時まで生きる変数の参照って意味で後者はもしTに参照があったらそれは'static以上生きるって解釈であってるんか?
ワイは低脳だから躓いてるンゴ
例えば&'static TとT: 'staticの違いがなんかあるらしいんやがわからなかったンゴ
前者はプログラム終了時まで生きる変数の参照って意味で後者はもしTに参照があったらそれは'static以上生きるって解釈であってるんか?
550デフォルトの名無しさん
2022/06/08(水) 11:49:32.36ID:oyhrGaRU いや理解したんご
前者は参照型しか受け付けないけど後者はそれ以上の種類の型を受け付けるンゴねえ
さらに違いがあるかもだけど勉強進めるわ
なんでもなかった
前者は参照型しか受け付けないけど後者はそれ以上の種類の型を受け付けるンゴねえ
さらに違いがあるかもだけど勉強進めるわ
なんでもなかった
551デフォルトの名無しさん
2022/06/08(水) 12:37:42.94ID:C5b6ywPX552デフォルトの名無しさん
2022/06/08(水) 14:46:42.18ID:JNpA1ROM553デフォルトの名無しさん
2022/06/08(水) 15:00:02.66ID:0R8j40RZ554デフォルトの名無しさん
2022/06/08(水) 15:48:23.76ID:kiLfNcoT555デフォルトの名無しさん
2022/06/08(水) 17:10:39.22ID:C5b6ywPX556デフォルトの名無しさん
2022/06/08(水) 17:16:08.77ID:LlAtoLIj これだけ時間をかけても原因すら分からずノンジェネリックとの速度差を埋められない状況をコストとして認識できてないのが恐ろしい
557デフォルトの名無しさん
2022/06/08(水) 17:31:51.50ID:H0oyRmek558デフォルトの名無しさん
2022/06/08(水) 18:18:03.20ID:cKPONsWM559デフォルトの名無しさん
2022/06/08(水) 18:32:47.55ID:y1p7Fxu2560デフォルトの名無しさん
2022/06/08(水) 19:11:11.80ID:sj9oTS9C561デフォルトの名無しさん
2022/06/08(水) 19:45:52.60ID:btlg3B6B562デフォルトの名無しさん
2022/06/08(水) 19:54:30.37ID:hF0KVPZD CheckedAddAssignの定義難しいよね
cloneを減らせるうまい定義見せて欲しい
cloneを減らせるうまい定義見せて欲しい
563デフォルトの名無しさん
2022/06/08(水) 19:58:01.42ID:hF0KVPZD >>560
> 一方でノンジェネリックで書いてもオーバフロー対策としてchecked_addは使わざるを得ない
つまりどちらが有利とか優れているとかいう問題ではない
BigUintの場合はオーバーフローを想定しなくて良いからただのAddAssignで良いよね
ジェネリックな実装の場合は考慮すべき事項が増えるというハンデを抱えている
> 一方でノンジェネリックで書いてもオーバフロー対策としてchecked_addは使わざるを得ない
つまりどちらが有利とか優れているとかいう問題ではない
BigUintの場合はオーバーフローを想定しなくて良いからただのAddAssignで良いよね
ジェネリックな実装の場合は考慮すべき事項が増えるというハンデを抱えている
564デフォルトの名無しさん
2022/06/08(水) 20:09:35.76ID:Pauu0yN9 基地同士の喧嘩おもすれー
565デフォルトの名無しさん
2022/06/08(水) 21:16:33.76ID:zfNTYu3X ジェネリックでなくても各i8版~u128版でchecked_add要るんじゃね?
566デフォルトの名無しさん
2022/06/08(水) 21:31:30.99ID:uKz/tAPi567デフォルトの名無しさん
2022/06/08(水) 22:52:52.99ID: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
>>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
568デフォルトの名無しさん
2022/06/08(水) 23:10:54.19ID:Pauu0yN9 Rust使うやつは全員クズ
569デフォルトの名無しさん
2022/06/08(水) 23:14:19.56ID:xZpQpCco ゴミみてぇに使いにくい
570デフォルトの名無しさん
2022/06/08(水) 23:33:46.23ID:1Qgkgfnu >>567
ジェネリックは遅くて使い物にならずRustはクソ言語のいい流れが出来ていたのに邪魔すんなボケ
ジェネリックは遅くて使い物にならずRustはクソ言語のいい流れが出来ていたのに邪魔すんなボケ
571デフォルトの名無しさん
2022/06/09(木) 00:05:50.09ID:8AO4ag5u572デフォルトの名無しさん
2022/06/09(木) 01:08:31.17ID:b8HehfnZ573デフォルトの名無しさん
2022/06/09(木) 09:43:05.84ID:m8hzuB37574デフォルトの名無しさん
2022/06/09(木) 11:12:09.28ID:5tn+SNbG 複オジ必死やなw
575デフォルトの名無しさん
2022/06/09(木) 11:39:59.58ID:gQa8Lild iterなんだけど
let v = vec![1, 2, 3, 4];
v.iter().filter(|&x| x % 2 == 0).cloned().collect();
v.iter().map(|&x| x * 2).collect();
filter()はcloned()が必要でなぜmap()は必要ないのか
let v = vec![1, 2, 3, 4];
v.iter().filter(|&x| x % 2 == 0).cloned().collect();
v.iter().map(|&x| x * 2).collect();
filter()はcloned()が必要でなぜmap()は必要ないのか
576デフォルトの名無しさん
2022/06/09(木) 11:41:07.83ID:gQa8Lild まちがえたこうだ
let v = vec![1, 2, 3, 4];
let result_1 = v.iter().filter(|&x| x % 2 == 0).cloned().collect();
let result_2 = v.iter().map(|&x| x * 2).collect();
let v = vec![1, 2, 3, 4];
let result_1 = v.iter().filter(|&x| x % 2 == 0).cloned().collect();
let result_2 = v.iter().map(|&x| x * 2).collect();
577デフォルトの名無しさん
2022/06/09(木) 11:52:52.81ID:WWB1ag70578デフォルトの名無しさん
2022/06/09(木) 14:32:02.03ID:BXa7hn4f 「Atom」の開発者が究極のコードエディターを目指す ~「Zed」の開発が始動
「Electron」を捨て、Rust言語を採用。GPUI、tree-sitterなどで武装し、超高速なコードエディターに
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1374986.html
「Electron」を捨て、Rust言語を採用。GPUI、tree-sitterなどで武装し、超高速なコードエディターに
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1374986.html
579デフォルトの名無しさん
2022/06/09(木) 14:58:44.89ID:G7q6UoxI 「重要」でスレ内検索かけると……
580デフォルトの名無しさん
2022/06/09(木) 16:58:07.35ID:/uOnDbzK >>575
Vec<i32>のiter()は&i32のイテレータ
filterした結果も&i32なのでVec<i32>でcollectしたければcopiedやclonedが必要
Vec<&i32>のままcollectするならclonedは不要
mapの例はx * 2でi32が新たに生成され
map以降は&i32ではなくi32のイテレータになるので
cloned無しでVec<i32>にcollectできる
Vec<i32>のiter()は&i32のイテレータ
filterした結果も&i32なのでVec<i32>でcollectしたければcopiedやclonedが必要
Vec<&i32>のままcollectするならclonedは不要
mapの例はx * 2でi32が新たに生成され
map以降は&i32ではなくi32のイテレータになるので
cloned無しでVec<i32>にcollectできる
581デフォルトの名無しさん
2022/06/09(木) 17:07:43.03ID:3qzGL8h6 >>577
Rc版はmake_mutにすれば呼び出し側が参照をつかんでる時だけcloneにフォールバックしてくれる
つかんでなければcloneしないので高速
全ての値をつかむようならRcを使わないやり方より少し遅くなる
Rc版はmake_mutにすれば呼び出し側が参照をつかんでる時だけcloneにフォールバックしてくれる
つかんでなければcloneしないので高速
全ての値をつかむようならRcを使わないやり方より少し遅くなる
582デフォルトの名無しさん
2022/06/09(木) 20:30:30.68ID:sXhLSFat >>355はRustだと末尾呼び出しの最適化が効くの?
末尾呼び出し最適化必須のschemeですら自動的には最適化されず、人間が意味を解析して、アキュムレーター使って末尾再帰になるようにしましょうって練習問題になるくらいなのに。
Rust凄い!!
末尾呼び出し最適化必須のschemeですら自動的には最適化されず、人間が意味を解析して、アキュムレーター使って末尾再帰になるようにしましょうって練習問題になるくらいなのに。
Rust凄い!!
583デフォルトの名無しさん
2022/06/09(木) 21:24:26.48ID:xbJg8ij+ >>581
簡易的なstreaming iteratorにする方法もあるよ
簡易的なstreaming iteratorにする方法もあるよ
584はちみつ餃子 ◆8X2XSCHEME
2022/06/09(木) 22:43:27.67ID:k8dtcEck585デフォルトの名無しさん
2022/06/10(金) 00:02:10.12ID:/2sYVq21 https://twitter.com/Ray__March/status/1523717266730151936
Crab Rave
https://twitter.com/5chan_nel (5ch newer account)
Crab Rave
https://twitter.com/5chan_nel (5ch newer account)
586582
2022/06/10(金) 12:26:19.22ID:xMTaqdcz >>584
340くらいから末尾呼び出し最適化の話題があって、355の2で「リリースモードだとスタックが溢れない」と書いてあったので、末尾呼び出し最適化が効いたのかと思いました。
十分なスタック容量があっただけ?
1+count(n-1)
を
count(n-1, acc+1)
に書き換えてくれる最適化があるのかな、と思いまして
340くらいから末尾呼び出し最適化の話題があって、355の2で「リリースモードだとスタックが溢れない」と書いてあったので、末尾呼び出し最適化が効いたのかと思いました。
十分なスタック容量があっただけ?
1+count(n-1)
を
count(n-1, acc+1)
に書き換えてくれる最適化があるのかな、と思いまして
587デフォルトの名無しさん
2022/06/10(金) 12:39:41.49ID:awrGQFqA588デフォルトの名無しさん
2022/06/10(金) 12:44:00.71ID:NmVzwec3589デフォルトの名無しさん
2022/06/10(金) 13:14:03.27ID:/2sYVq21 streaming iterator! そういうのもあるのか
自分への参照を返せるんだね
使うかどうかは分からんけど覚えておこう
自分への参照を返せるんだね
使うかどうかは分からんけど覚えておこう
591はちみつ餃子 ◆8X2XSCHEME
2022/06/10(金) 20:18:18.95ID:din4Kjb/ >>586
すでに >>587 が指摘しているが、定数畳み込みが起こっている。 入力が定数で、かつそれに対する演算が副作用のない基本的なものであった場合に定数畳み込みがされやすい。 定数ではない場合でもこの関数 count は
mov rax, rdi
ret
になってて、入力をそのまま返す形にまで最適化されるので末尾呼出しがどうこうというレベルのものではなくなっている。
最適化というのは、レジスタ割り当てなどは理論的な背景がはっきりしているが、多くの細々としたものは「大量の置き換えパターンを辞書のように持っている」という物量で押し切る泥臭いものだったりするので (それをやりやすいようなデータ構造とかに工夫はあると思うが) 結局のところは投入されたリソースが多いやつが強い。
ちなみに Scheme の末尾呼出し最適化は言語仕様で要求する最低限度がそれだけ (しかし常にやらなければならない) という意味であって、それ以上の最適化をやっちゃ駄目という意味ではないよ。 最適化をどのレベルまでやるかは処理系次第。
すでに >>587 が指摘しているが、定数畳み込みが起こっている。 入力が定数で、かつそれに対する演算が副作用のない基本的なものであった場合に定数畳み込みがされやすい。 定数ではない場合でもこの関数 count は
mov rax, rdi
ret
になってて、入力をそのまま返す形にまで最適化されるので末尾呼出しがどうこうというレベルのものではなくなっている。
最適化というのは、レジスタ割り当てなどは理論的な背景がはっきりしているが、多くの細々としたものは「大量の置き換えパターンを辞書のように持っている」という物量で押し切る泥臭いものだったりするので (それをやりやすいようなデータ構造とかに工夫はあると思うが) 結局のところは投入されたリソースが多いやつが強い。
ちなみに Scheme の末尾呼出し最適化は言語仕様で要求する最低限度がそれだけ (しかし常にやらなければならない) という意味であって、それ以上の最適化をやっちゃ駄目という意味ではないよ。 最適化をどのレベルまでやるかは処理系次第。
592デフォルトの名無しさん
2022/06/10(金) 20:27:25.22ID:VliTcE7P こいつが出てくると結論が1つも分からなくなる
593デフォルトの名無しさん
2022/06/10(金) 21:05:43.32ID:uz7MKgqc 複オジと同じ臭い
594デフォルトの名無しさん
2022/06/10(金) 21:45:41.77ID:iyAWtrh4 汚文章は汚コードの兄弟
同じ親から生まれてくるもの
同じ親から生まれてくるもの
595デフォルトの名無しさん
2022/06/10(金) 22:32:01.13ID:r0Sf5PMX 最適化の話はかなりコンパイラーに詳しくないとなぜそうなるかって分からないだろうからな
コンパイラーの最適化について話せる奴はプログラミング中級者以上だろ。
(本職プログラマなら話せないと知識なさすぎと言われるだろうが)
趣味でプの俺は永遠に初心者レベルでそんな知識ないから、こいつ何を言っているんだ?だが
コンパイラーの最適化について話せる奴はプログラミング中級者以上だろ。
(本職プログラマなら話せないと知識なさすぎと言われるだろうが)
趣味でプの俺は永遠に初心者レベルでそんな知識ないから、こいつ何を言っているんだ?だが
596デフォルトの名無しさん
2022/06/10(金) 22:32:11.19ID:+N1EN6wu まぁ要するに
×××という最適化処理が処理系の規格として定められているのなら処理系の開発者(=コンパイラとか作る人)はその最適化を実現しないといけないしそれを利用するプログラマは処理系が”上手いことやってくれる”と期待していい、しかしそれが言語規格上は必須とされてない処理については処理系が“うまいことやつてくれる”と基本は期待してはいけない
けど、規格で求められてないような高度な最適化処理を“してはいけない”わけではない、最新の理論で見つかった最適化処理など取り入れる分には好きにして構わない
という意味でしょ
Haskellのメモ化処理とかでもよく出てくるよ
GHCって言うすごい処理系があってHaskellの標準規格では全然定められてないような最適化処理をバンバンやってくれるから“なんでこんなにはやいの?とりま作っただけなのに”と思うこと時々あるからな
×××という最適化処理が処理系の規格として定められているのなら処理系の開発者(=コンパイラとか作る人)はその最適化を実現しないといけないしそれを利用するプログラマは処理系が”上手いことやってくれる”と期待していい、しかしそれが言語規格上は必須とされてない処理については処理系が“うまいことやつてくれる”と基本は期待してはいけない
けど、規格で求められてないような高度な最適化処理を“してはいけない”わけではない、最新の理論で見つかった最適化処理など取り入れる分には好きにして構わない
という意味でしょ
Haskellのメモ化処理とかでもよく出てくるよ
GHCって言うすごい処理系があってHaskellの標準規格では全然定められてないような最適化処理をバンバンやってくれるから“なんでこんなにはやいの?とりま作っただけなのに”と思うこと時々あるからな
597デフォルトの名無しさん
2022/06/10(金) 22:36:04.99ID:3HE2W+m8 最適化と言えば&mutがnoaliasになって高速化したコード出会ったことある人居る?
598デフォルトの名無しさん
2022/06/10(金) 22:56:48.93ID:/Qg1cUoJ599デフォルトの名無しさん
2022/06/10(金) 23:03:01.48ID:EifRM46R >>595
初心者自演乙オジ
初心者自演乙オジ
600デフォルトの名無しさん
2022/06/10(金) 23:39:18.10ID:QxuEFd4p またいつもと同じパターン
善人 = 情報や説明やコード等を書いてくれる人
悪人 = 文句や批判だけの人
>>597
Rustでは基本的に二つの & mut がaliasになることはないからnoaliasでいいけど
LLVMのバグが見つかったりやRustコンパイラの改修などで変遷を経てきてるみたいね
> Rust 1.0 ~ 1.7 noalias enabled
> Rust 1.8 ~ 1.27 noalias disabled
> Rust 1.28 ~ 1.29 noalias enabled
> Rust 1.30 ~ 1.54 noalias disabled
> Rust 1.54 ~ noalias enabled
善人 = 情報や説明やコード等を書いてくれる人
悪人 = 文句や批判だけの人
>>597
Rustでは基本的に二つの & mut がaliasになることはないからnoaliasでいいけど
LLVMのバグが見つかったりやRustコンパイラの改修などで変遷を経てきてるみたいね
> Rust 1.0 ~ 1.7 noalias enabled
> Rust 1.8 ~ 1.27 noalias disabled
> Rust 1.28 ~ 1.29 noalias enabled
> Rust 1.30 ~ 1.54 noalias disabled
> Rust 1.54 ~ noalias enabled
601デフォルトの名無しさん
2022/06/10(金) 23:52:37.74ID:q3uEdydr 仕様ころころゴミ言語
602デフォルトの名無しさん
2022/06/10(金) 23:57:33.08ID:Vy8jfUtT ソースこれですか
https://stackoverflow.com/a/57259339
https://stackoverflow.com/a/57259339
603デフォルトの名無しさん
2022/06/11(土) 00:21:37.71ID:nVHax23k604デフォルトの名無しさん
2022/06/11(土) 00:47:00.69ID:41aFXNPT605デフォルトの名無しさん
2022/06/11(土) 00:53:30.81ID:6T6IERuk そんなつまんねーのに反応すんなよ……
606デフォルトの名無しさん
2022/06/11(土) 01:51:51.23ID:coFBEVyx マッチポンピング好きだねぇ
607デフォルトの名無しさん
2022/06/11(土) 11:14:20.05ID:FpznSlgy そろそろRust製の有名なソフトウェア作ってからビックマウスしてくださいね、Firefox以外で
608デフォルトの名無しさん
2022/06/11(土) 11:39:14.69ID:fd4RDbWP >>606
マッチポンプも過疎スレのにぎわい
マッチポンプも過疎スレのにぎわい
609デフォルトの名無しさん
2022/06/11(土) 11:54:00.75ID:sRR0HfwK TechEmpower Round 18で1.5倍の差を付けて堂々の1位をかっさらったactixは有名ソフトウェアではない了解
610デフォルトの名無しさん
2022/06/11(土) 15:51:26.10ID:Lxou0O6d DiscordとかDropboxとか
611デフォルトの名無しさん
2022/06/11(土) 16:19:59.18ID:C3/u0lQ5 WinとかLinuxの中身ですでに使われてなかった?
612デフォルトの名無しさん
2022/06/11(土) 18:52:01.33ID:BGPUwt90 >>593
同じ臭いも何も同一人物だろ
同じ臭いも何も同一人物だろ
613デフォルトの名無しさん
2022/06/11(土) 19:26:39.50ID:WsHL0uxM614デフォルトの名無しさん
2022/06/11(土) 23:25:25.63ID:HlAQKNMT なんでRound18なんて大昔の過去を?
615デフォルトの名無しさん
2022/06/12(日) 06:12:09.52ID:6S+GFICB616デフォルトの名無しさん
2022/06/12(日) 17:11:51.09ID:tUHADwRi Rustはver2.0にはなりませんって言ってるけど実質はとっくの昔にver2.0になってる
617デフォルトの名無しさん
2022/06/12(日) 19:14:45.66ID:geXDvND7 >>616
どういうこと?
どういうこと?
618デフォルトの名無しさん
2022/06/12(日) 20:36:02.36ID:nrxswUhC >>562 >>566
CheckedAddAssignにこだわる必要はないため、発想を転換して、
checked_add()の原関数であるoverflowing_add()を用いることで、
overflowing_add_assign()を用意して同じようにbool値を返せば解決する
具体的には以下のように引数はadd_assign()と同じでbool値を返せばよい
trait OverflowingAddAssign {
fn overflowing_add_assign(&mut self, rhs: &Self) -> bool;
}
オーバーフローするi8型〜u128型にはoverflowing_add()があるため実装はこうなる
let is_overflow;
(*self, is_overflow) = self.overflowing_add(*rhs);
is_overflow
この3行のコードでちゃんと最適化されるかどうかを確認するため、
単純にadd_assignを用いた場合、すなわち「*self += rhs」と比較すると
https://godbolt.org/z/WP3En8xM8
のアセンブリ出力となり、オーバーフローを返す以外は同一に最適化されることが確認できる
一方でオーバーフローしないBigUintなどの型への実装はこうなる
*self += rhs;
false
つまりオーバーフローの結果として常にfalseを返すので、
こちらは使う側でオーバーフローの扱いが消えてadd_assign部分のみに最適化される
したがってこのOverflowingAddAssignを用いてジェネリックに書けば、
どちらの型の場合であっても、非ジェネリックに書いた時と同一コードとなる
CheckedAddAssignにこだわる必要はないため、発想を転換して、
checked_add()の原関数であるoverflowing_add()を用いることで、
overflowing_add_assign()を用意して同じようにbool値を返せば解決する
具体的には以下のように引数はadd_assign()と同じでbool値を返せばよい
trait OverflowingAddAssign {
fn overflowing_add_assign(&mut self, rhs: &Self) -> bool;
}
オーバーフローするi8型〜u128型にはoverflowing_add()があるため実装はこうなる
let is_overflow;
(*self, is_overflow) = self.overflowing_add(*rhs);
is_overflow
この3行のコードでちゃんと最適化されるかどうかを確認するため、
単純にadd_assignを用いた場合、すなわち「*self += rhs」と比較すると
https://godbolt.org/z/WP3En8xM8
のアセンブリ出力となり、オーバーフローを返す以外は同一に最適化されることが確認できる
一方でオーバーフローしないBigUintなどの型への実装はこうなる
*self += rhs;
false
つまりオーバーフローの結果として常にfalseを返すので、
こちらは使う側でオーバーフローの扱いが消えてadd_assign部分のみに最適化される
したがってこのOverflowingAddAssignを用いてジェネリックに書けば、
どちらの型の場合であっても、非ジェネリックに書いた時と同一コードとなる
619デフォルトの名無しさん
2022/06/12(日) 20:47:24.48ID:nrxswUhC >>577
一般的に参照返すイテレータ類を実装する場合の注意点として、
1. let x0 = x_iter.next();
2. let x1 = x_iter.next();
3. ここで x0 の指す値を使う
順にこのような使い方をした時の挙動として、以下4パターンが考えられる
A. ✕ 実行時エラーとなる
B. ✕ x0の指す値が変化してしまう (次のx1の指す値と同一になってしまう)
C. ○ x0もx1もそれぞれ正しい値を指す
D. ○ コンパイル時エラーとなる
Rcとget_mut()を使った>>511のコードがNGのパターンA.で、これを避けるために、
Rc<RefCell>を使う提案のようだが、それもNGのパターンB.となってしまう
Rcとmake_mut()を使えばパターンC.となり、これがRc利用の場合の解となる
しかし参照を返すイテレータ自身がmake_mut()でclone()するのは役割として過剰である
切り分けとしてはイテレータを使う側が必要に応じてclone()するのが望ましい
そういうコードへ適切に誘導できる道が、コンパイル時エラーで示すパターンD.
具体的には、似非IteratorであるStreamingIteratorを用いるか、
Rust本命のGATsを用いたLendingIterator (=GATs適用後のIterator) を用いると、
clone()が必要な場面ではコンパイル時エラーにより知らせてくれる
もちろん普通にnext()ループ内の利用ならばclone()の必要なくコンパイルが通る
一般的に参照返すイテレータ類を実装する場合の注意点として、
1. let x0 = x_iter.next();
2. let x1 = x_iter.next();
3. ここで x0 の指す値を使う
順にこのような使い方をした時の挙動として、以下4パターンが考えられる
A. ✕ 実行時エラーとなる
B. ✕ x0の指す値が変化してしまう (次のx1の指す値と同一になってしまう)
C. ○ x0もx1もそれぞれ正しい値を指す
D. ○ コンパイル時エラーとなる
Rcとget_mut()を使った>>511のコードがNGのパターンA.で、これを避けるために、
Rc<RefCell>を使う提案のようだが、それもNGのパターンB.となってしまう
Rcとmake_mut()を使えばパターンC.となり、これがRc利用の場合の解となる
しかし参照を返すイテレータ自身がmake_mut()でclone()するのは役割として過剰である
切り分けとしてはイテレータを使う側が必要に応じてclone()するのが望ましい
そういうコードへ適切に誘導できる道が、コンパイル時エラーで示すパターンD.
具体的には、似非IteratorであるStreamingIteratorを用いるか、
Rust本命のGATsを用いたLendingIterator (=GATs適用後のIterator) を用いると、
clone()が必要な場面ではコンパイル時エラーにより知らせてくれる
もちろん普通にnext()ループ内の利用ならばclone()の必要なくコンパイルが通る
620デフォルトの名無しさん
2022/06/12(日) 20:59:35.22ID:nrxswUhC 実際に >>618のOverflowingAddAssignを用いてLendingIteratorで実装すると
以下のようになり、GATsを用いている以外は現状のIteratorともちろん同じ形
自己参照を返せるようになった点のみ異なる
impl<T: OverflowingAddAssign> LendingIterator for Fibonacci<T> {
type Item<'a> = &'a T where Self: 'a;
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
if self.is_overflow {
return None;
}
if self.is_first {
self.is_first = false;
} else {
self.is_overflow = self.p.overflowing_add_assign(&self.q);
std::mem::swap(&mut self.p, &mut self.q);
}
Some(&self.p)
}
}
is_first処理は >>511のコードでの「iter::once(p.clone()).chain(...」部分であり必須
また、前述のようにBigUintで用いれば is_overflow が常にfalseのため最適化で消えて、
値の更新部分は「self.p += &self.q」のみが残り非ジェネリックと同一コードとなる
したがって、上述のコードがどの型でも最善に動作するコードとなるだろう
以下のようになり、GATsを用いている以外は現状のIteratorともちろん同じ形
自己参照を返せるようになった点のみ異なる
impl<T: OverflowingAddAssign> LendingIterator for Fibonacci<T> {
type Item<'a> = &'a T where Self: 'a;
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
if self.is_overflow {
return None;
}
if self.is_first {
self.is_first = false;
} else {
self.is_overflow = self.p.overflowing_add_assign(&self.q);
std::mem::swap(&mut self.p, &mut self.q);
}
Some(&self.p)
}
}
is_first処理は >>511のコードでの「iter::once(p.clone()).chain(...」部分であり必須
また、前述のようにBigUintで用いれば is_overflow が常にfalseのため最適化で消えて、
値の更新部分は「self.p += &self.q」のみが残り非ジェネリックと同一コードとなる
したがって、上述のコードがどの型でも最善に動作するコードとなるだろう
621デフォルトの名無しさん
2022/06/12(日) 21:33:27.12ID:HOCAPH7I NAVERまとめを彷彿とさせるレス乙
3~4日もかけて頑張って調べたのは讃えるが
特質の異なるものを必要もなくジェネリック化することがアンチパターンだということに早く気づいてね
3~4日もかけて頑張って調べたのは讃えるが
特質の異なるものを必要もなくジェネリック化することがアンチパターンだということに早く気づいてね
622デフォルトの名無しさん
2022/06/12(日) 21:51:32.06ID:rC/Ton17 これは同じものだからジェネリックでいいんじゃね
623デフォルトの名無しさん
2022/06/12(日) 22:02:56.78ID:geXDvND7624デフォルトの名無しさん
2022/06/12(日) 22:16:28.43ID:McWr7xMA add系は#[inline]だから大丈夫
625デフォルトの名無しさん
2022/06/12(日) 22:22:02.34ID:geXDvND7 >>624
構造体メンバの値はグローバル変数なんかと同じで関数外で値が変更される可能性があるので
メンバが特定の値しか取らないことを暫定として最適化するためには、
crateの範囲を超えてプログラム全体で値が設定されうる箇所が他にないことを確認するか
メンバが可視な範囲で確認する必要があると思うけど、
前者をやるためにはリンク時最適化が必要だし
後者ならメンバの可視性をLLVMに渡さないといけないと思う
rustcとLLVMはそこまでやってるの?
構造体メンバの値はグローバル変数なんかと同じで関数外で値が変更される可能性があるので
メンバが特定の値しか取らないことを暫定として最適化するためには、
crateの範囲を超えてプログラム全体で値が設定されうる箇所が他にないことを確認するか
メンバが可視な範囲で確認する必要があると思うけど、
前者をやるためにはリンク時最適化が必要だし
後者ならメンバの可視性をLLVMに渡さないといけないと思う
rustcとLLVMはそこまでやってるの?
626デフォルトの名無しさん
2022/06/12(日) 22:54:00.11ID:E86JsxIR rust結構面白いからマイクロソフトがVisualStudioでRustでWindowsFormを作れるようにしてくれればなあ
627デフォルトの名無しさん
2022/06/12(日) 22:59:17.60ID:MphJhZqp628デフォルトの名無しさん
2022/06/12(日) 23:07:42.57ID:McWr7xMA >>627
assignでない演算は生成のため内部でcloneが発生して無駄と既に結論が出ている
assignでない演算は生成のため内部でcloneが発生して無駄と既に結論が出ている
629デフォルトの名無しさん
2022/06/12(日) 23:11:14.31ID:0LaPlWrL GATがstableになるの意外と近い予定なんだな
年単位で先のことかと思ってた
年単位で先のことかと思ってた
630デフォルトの名無しさん
2022/06/12(日) 23:18:22.58ID:H16c0lbs >>625
Rustでそれは起きない
書き換えるには所有権か&mutが必要でコンパイラは全て把握している
更に構造体のメンバーはpub指定がない限り他者はアクセス不能
つまり今回ならばnext()しかメンバー書き換えしないとコンパイラは確定できる
Rustでそれは起きない
書き換えるには所有権か&mutが必要でコンパイラは全て把握している
更に構造体のメンバーはpub指定がない限り他者はアクセス不能
つまり今回ならばnext()しかメンバー書き換えしないとコンパイラは確定できる
631デフォルトの名無しさん
2022/06/12(日) 23:25:01.40ID:geXDvND7 >>630
その最適化するのはLLVMだけどLLVMが最適化できるだけの情報を渡してるの?というのが聞きたいこと
その最適化するのはLLVMだけどLLVMが最適化できるだけの情報を渡してるの?というのが聞きたいこと
632デフォルトの名無しさん
2022/06/13(月) 00:14:58.10ID:RutuvYDu >>623
その通りRustコンパイラが賢いことを確認したよ
is_overflowが常にfalseとなることを察知してNoneを返すことが無くなったみたい
Noneが来ない利用側のwhile let Some(n) = iter.next()は無限ループのコードとなっちゃった
さらにwhile loopより後ろのコードは永遠未達と判断されて完全に消えた
その通りRustコンパイラが賢いことを確認したよ
is_overflowが常にfalseとなることを察知してNoneを返すことが無くなったみたい
Noneが来ない利用側のwhile let Some(n) = iter.next()は無限ループのコードとなっちゃった
さらにwhile loopより後ろのコードは永遠未達と判断されて完全に消えた
633デフォルトの名無しさん
2022/06/13(月) 00:32:02.84ID:XmIGhHAx634デフォルトの名無しさん
2022/06/13(月) 00:46:44.89ID:BEV+i+nu >>620
GATってIteratorとか既存TraitのAssosiate Typeに直接ライフタイム書けない仕様になったの?
LendingIteratorみたいに別のTraitを使わないといけないようならイテレータ関連の仕組みが2重なって使い勝手が悪い
GATってIteratorとか既存TraitのAssosiate Typeに直接ライフタイム書けない仕様になったの?
LendingIteratorみたいに別のTraitを使わないといけないようならイテレータ関連の仕組みが2重なって使い勝手が悪い
635デフォルトの名無しさん
2022/06/13(月) 00:50:16.18ID:WmCB7dh7636デフォルトの名無しさん
2022/06/13(月) 00:56:09.87ID:WmCB7dh7637デフォルトの名無しさん
2022/06/13(月) 12:04:19.24ID:GDAgVCx4 >>632
おー、そんな賢いんだ。すごい
ちなみにfn mainとイテレータの定義は同じcrateに含まれている?
lib crateでイテレータを定義してbin crateから使った場合にどうなるかも気になる
おー、そんな賢いんだ。すごい
ちなみにfn mainとイテレータの定義は同じcrateに含まれている?
lib crateでイテレータを定義してbin crateから使った場合にどうなるかも気になる
638デフォルトの名無しさん
2022/06/13(月) 14:28:57.42ID:HonuYlRO639デフォルトの名無しさん
2022/06/13(月) 17:16:12.55ID:GB/2aB1F やめてくれ
汚コードまみれになる
汚コードまみれになる
640デフォルトの名無しさん
2022/06/13(月) 19:44:34.63ID:oVc0GyRX 乱数系のモジュールの仕様変更がかなりガッツリあったみたいなんだけど
Rustってこういうことよく起るの?
なんかWeb系みたいなノリを感じたんだが合ってる?
Rustってこういうことよく起るの?
なんかWeb系みたいなノリを感じたんだが合ってる?
641デフォルトの名無しさん
2022/06/13(月) 19:57:14.15ID:86dwWfAN なんのはなしだ
642デフォルトの名無しさん
2022/06/13(月) 19:58:13.01ID:8KDu5nut >>640
人に読んでもらう文章は重要なところ省いたら読んでもらえないよ
人に読んでもらう文章は重要なところ省いたら読んでもらえないよ
643デフォルトの名無しさん
2022/06/13(月) 19:59:25.24ID:GDAgVCx4 >>640
標準ライブラリで破壊的変更はほとんどない
外部crateなら概ねsemverに従ってるし lockfile の仕組みもあるから、
以前ビルドできていたものがビルドできなくなることもほとんどない
標準ライブラリで破壊的変更はほとんどない
外部crateなら概ねsemverに従ってるし lockfile の仕組みもあるから、
以前ビルドできていたものがビルドできなくなることもほとんどない
644デフォルトの名無しさん
2022/06/13(月) 20:37:45.98ID:XXqnAuVB >>638
サポートってどの程度のサポートを期待しているんだ?
MSがRustコンパイラー出せばWindowsのRust用フレームワーク出すんだろうがな
出さないなら、C/C++/C#のAPI/フレームワークをRustからとりあえず使えるようにしました
程度のサポートになるだろう。
期待しているのはRust用フレームワークであってRustからとりあえず使えるよじゃないだろ?
サポートってどの程度のサポートを期待しているんだ?
MSがRustコンパイラー出せばWindowsのRust用フレームワーク出すんだろうがな
出さないなら、C/C++/C#のAPI/フレームワークをRustからとりあえず使えるようにしました
程度のサポートになるだろう。
期待しているのはRust用フレームワークであってRustからとりあえず使えるよじゃないだろ?
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★4 [ぐれ★]
- 【音楽】Perfume・あ~ちゃんの結婚相手「一般男性」は吉田カバンの社長・吉田幸裕氏(41) 高身長で山本耕史似 [Ailuropoda melanoleuca★]
- 【大分】佐賀関で大規模火災、170棟以上が延焼中 70代男性1人と連絡取れず [ぐれ★]
- 【サッカー】U-17日本代表、激闘PK戦制す 北朝鮮撃破で6大会ぶり8強入り U17W杯 [久太郎★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
- 【サッカー】日本代表、ボリビアに3発快勝 森保監督通算100試合目を飾る…鎌田、町野、中村がゴール [久太郎★]
- アンケート調査で「高市発言は問題なし」 93.5%wwwwwwwwwwwwwwwwwwwwwwwww [279254606]
- 寝癖ってどうしたらつかなくなるんや?
- 自閉症が「んなっしょい」と連呼するお🏡
- 【画像】エロい一般漫画はなぜこんなに抜けるのか
- BTSのバラエティ面白すぎワロタ
- 自民党議員「高市は先人が築き上げた日中関係を壊した。外務省が謝罪に言ってるが自分で責任を取れ」 [834922174]
