C++ vs Rust
■ このスレッドは過去ログ倉庫に格納されています
2021/04/24(土) 08:04:49.48ID:nPKzA798
競え
2021/04/24(土) 09:03:31.43ID:CqGuC/ho
何で?
2021/04/24(土) 09:10:09.42ID:MAG7Rri7
どちらも変なプライド拗らせたアホしかいない印象
4デフォルトの名無しさん
2021/04/24(土) 10:50:18.68ID:N1eYD/7j C++: カミソリ
Rust: 安全カミソリ
Rust: 安全カミソリ
2021/04/24(土) 11:18:00.79ID:gMqF1SGc
別に〜
裏方一緒だし
裏方一緒だし
2021/04/25(日) 11:37:52.88ID:vJWG11Gh
一概にどちらが優れているとは言えないことではあるが、
代入やコンストラクタが、moveとcopyのどちらになるかについて、Rustの
方が自動化が進んでいると思いがちだが、実際は、
C++は、関数の戻り値が構造体型/クラス型になっている場合に関しては
RVO(Return Value Optimization)が働き、右辺が
クラス名(実引数列)
の形式の一時オブジェクトである場合には、moveが選ばれるが、それ以外は、
概ねcopyになるので、ある意味では「自動選択」しているのに対し、
Rustでは、x = y と書いた場合、原則的には「デフォルトmove」の規則に
従い、copyしたい場合は、右辺をy.clone()と書くことになっていて、
「手動選択」を採用している。
C++は、どう書いた場合にmoveになり、どう書いた場合にcopyになるかを全て把握するのは
難しくて、C++の仕様が勉強不足だと勘違いや見落としが発生する可能性があるのに対し、
Rust方式は、moveとcopyのどちらになるかが明確なので混乱が少ないと言えるかも知れない。
つまり、このことに関しては、児童選択より手動選択の方が安心感があるかも知れない。
意見を求む。
代入やコンストラクタが、moveとcopyのどちらになるかについて、Rustの
方が自動化が進んでいると思いがちだが、実際は、
C++は、関数の戻り値が構造体型/クラス型になっている場合に関しては
RVO(Return Value Optimization)が働き、右辺が
クラス名(実引数列)
の形式の一時オブジェクトである場合には、moveが選ばれるが、それ以外は、
概ねcopyになるので、ある意味では「自動選択」しているのに対し、
Rustでは、x = y と書いた場合、原則的には「デフォルトmove」の規則に
従い、copyしたい場合は、右辺をy.clone()と書くことになっていて、
「手動選択」を採用している。
C++は、どう書いた場合にmoveになり、どう書いた場合にcopyになるかを全て把握するのは
難しくて、C++の仕様が勉強不足だと勘違いや見落としが発生する可能性があるのに対し、
Rust方式は、moveとcopyのどちらになるかが明確なので混乱が少ないと言えるかも知れない。
つまり、このことに関しては、児童選択より手動選択の方が安心感があるかも知れない。
意見を求む。
2021/04/25(日) 11:57:11.84ID:Ef2Yns/P
Copy trait実装してたら暗黙的に実行されるわ。
とはいえc++のそれよりかは分かり易いけど。
とはいえc++のそれよりかは分かり易いけど。
2021/04/25(日) 13:18:15.15ID:rtrHqrCb
[C++]
xやfunc()の戻り値が CPerson というクラス型の場合、
10. x = y; // copy代入。yの中味はxにコピーされる。yのデータも保存。
11. x = std::move(y) // move代入。yのデータは破棄される。
12. x = func(a); // move代入または、RVOが働いてmove代入以上に速い動作になる。
関数の戻り値だけは特別に処理されている。
[Rust]
(CPerson がCopy traitを実装して無い場合に限定)
20. x = y; // move。以後、y は使用できなくなる。これが故にデフォルトmoveと呼ばれる。
21. x = y.clone(); // copy。以後もyは使用できる。
22. x = func(a); // move。20.と同じ規則に従っているだけで関数の戻り値だから特別では無い。
C++の場合、12.で関数だけは特別処理されているのに対し、Rustの22では
関数でも特別処理されているわけではなく、20.のデフォルトmoveの原則に従っているだけ
のように見える。
C++の場合、11. では、std::move()で修飾すると、なぜか、10. で修飾しなかった場合
より、実行されるCPUの処理が「減る」。ソースコードで関数の様なものを
追加した方が追加しなかったときよりCPUの処理が減ってしまうのは、どことなく直感に
反する。
一方、Rustの21と20を比較すると、.clone()を書いた方が書かなかったときより、
実行されるCPUの処理が増えるので、直感的である。
この場合、.clone()を書いたことで「コピーするためにCPUの処理が追加された」という
直感に沿った感じになるから。
C++の場合、std::move()と書くと「std::move()という関数の様なものを書いたのに、
なぜか、CPUの処理が減る」という違和感を感じるようになる。
xやfunc()の戻り値が CPerson というクラス型の場合、
10. x = y; // copy代入。yの中味はxにコピーされる。yのデータも保存。
11. x = std::move(y) // move代入。yのデータは破棄される。
12. x = func(a); // move代入または、RVOが働いてmove代入以上に速い動作になる。
関数の戻り値だけは特別に処理されている。
[Rust]
(CPerson がCopy traitを実装して無い場合に限定)
20. x = y; // move。以後、y は使用できなくなる。これが故にデフォルトmoveと呼ばれる。
21. x = y.clone(); // copy。以後もyは使用できる。
22. x = func(a); // move。20.と同じ規則に従っているだけで関数の戻り値だから特別では無い。
C++の場合、12.で関数だけは特別処理されているのに対し、Rustの22では
関数でも特別処理されているわけではなく、20.のデフォルトmoveの原則に従っているだけ
のように見える。
C++の場合、11. では、std::move()で修飾すると、なぜか、10. で修飾しなかった場合
より、実行されるCPUの処理が「減る」。ソースコードで関数の様なものを
追加した方が追加しなかったときよりCPUの処理が減ってしまうのは、どことなく直感に
反する。
一方、Rustの21と20を比較すると、.clone()を書いた方が書かなかったときより、
実行されるCPUの処理が増えるので、直感的である。
この場合、.clone()を書いたことで「コピーするためにCPUの処理が追加された」という
直感に沿った感じになるから。
C++の場合、std::move()と書くと「std::move()という関数の様なものを書いたのに、
なぜか、CPUの処理が減る」という違和感を感じるようになる。
2021/04/25(日) 17:13:07.94ID:In1fvQYU
要はRustの代入ってmemcpyで、単純なmemcpyされると困るデータ(!Copy)の場合右辺がinvalidate(move)され使えなくなる
って理解がシンプルなのかな
って理解がシンプルなのかな
2021/04/25(日) 18:00:12.34ID:S2tV53BX
>>9
x = y の時、
結果的にはほとんどmemcpy(&x,&y,サイズ)に近い動作になっているかもしれないな。
ただ、右辺yの構造体メンバの中にRc<T>のような複雑なものが入っている場合、
結果は単純コピーのようになったとしても、コンパイラはもっと丁寧に処理
しているのではなかろうか。
x = y の時、
結果的にはほとんどmemcpy(&x,&y,サイズ)に近い動作になっているかもしれないな。
ただ、右辺yの構造体メンバの中にRc<T>のような複雑なものが入っている場合、
結果は単純コピーのようになったとしても、コンパイラはもっと丁寧に処理
しているのではなかろうか。
2021/04/26(月) 01:44:08.26ID:+85I2LX6
>>10
move は memcpy だよ
Rc も実体はヒープへのポインタだから memcpy で問題ない
memcpy してはいけない例としては async fn みたいな自己参照構造体などがあるけど
Pin をうまく使うことで変な状態にならないようにしている
move は memcpy だよ
Rc も実体はヒープへのポインタだから memcpy で問題ない
memcpy してはいけない例としては async fn みたいな自己参照構造体などがあるけど
Pin をうまく使うことで変な状態にならないようにしている
12デフォルトの名無しさん
2021/04/26(月) 17:23:54.42ID:92SW7900 c++に批判的な姿勢で知られるlinusがなぜrustにはwelcomeな態度取ってるのかが理解できない
rustだってメモリ安全性がなければc++みたいなもんだろ
rustだってメモリ安全性がなければc++みたいなもんだろ
2021/04/26(月) 17:27:49.70ID:oHxAx7LN
言うほどwelcomeか?
14デフォルトの名無しさん
2021/04/26(月) 17:29:26.57ID:92SW7900 >>13
貶すまではいってないじゃん
貶すまではいってないじゃん
15デフォルトの名無しさん
2021/04/26(月) 18:48:21.42ID:pZ6mft9e あわしろ氏もRustは凄いって言ってましたね。
C++をあまり好きじゃないところも同じ。
C++をあまり好きじゃないところも同じ。
2021/04/26(月) 20:08:40.47ID:cN+lbm0F
>>12
c++にもだいぶ甘くはなってるよ。
ただそれでもrustに対してもそこまで容認的ではない。
試しにドライバー書いてみれば?って言って試させてるが、まだまともには考えてないわ。
https://lkml.org/lkml/2021/4/16/901
c++にもだいぶ甘くはなってるよ。
ただそれでもrustに対してもそこまで容認的ではない。
試しにドライバー書いてみれば?って言って試させてるが、まだまともには考えてないわ。
https://lkml.org/lkml/2021/4/16/901
17デフォルトの名無しさん
2021/04/26(月) 20:27:04.95ID:92SW79002021/04/26(月) 20:51:20.12ID:cN+lbm0F
>>17
続きを読めば?どういう流れかわかるから。
続きを読めば?どういう流れかわかるから。
19デフォルトの名無しさん
2021/04/26(月) 21:27:22.23ID:92SW7900 >>18
続きで懐疑的な立場取ってんのlinusじゃなくね?
続きで懐疑的な立場取ってんのlinusじゃなくね?
2021/04/26(月) 22:53:32.32ID:cN+lbm0F
21デフォルトの名無しさん
2021/04/26(月) 23:32:00.78ID:92SW7900 >>20
じゃあレスすんなよカス
じゃあレスすんなよカス
2021/04/26(月) 23:47:01.17ID:cN+lbm0F
だから読めって。。文盲なんか?
2021/04/27(火) 00:14:36.96ID:H90KgUtd
>>20
moonshotって言ってるの割り込みコンテキストでallocator呼び出すことをコンパイル時にチェックできるようにしたいという話では
現実的には関数ごとにどのコンテキストで呼び出せるものなのかタグ付けしてるとかなんとか
綺麗じゃないけど、まあ動くわなという解決策
つまみ食いしかしてないから読み違えてるかも知れないけど
これをもってlinuxカーネルにrust取り込むのを否定するような話ではないようにみえた
他にもmoonshotって言ってる箇所ある?
moonshotって言ってるの割り込みコンテキストでallocator呼び出すことをコンパイル時にチェックできるようにしたいという話では
現実的には関数ごとにどのコンテキストで呼び出せるものなのかタグ付けしてるとかなんとか
綺麗じゃないけど、まあ動くわなという解決策
つまみ食いしかしてないから読み違えてるかも知れないけど
これをもってlinuxカーネルにrust取り込むのを否定するような話ではないようにみえた
他にもmoonshotって言ってる箇所ある?
2021/04/27(火) 01:12:51.08ID:VJIOoOWO
一通り読んだけど他にmoonshotって言ってるとこはなかったような。
2021/04/27(火) 08:00:23.09ID:/+bIFNU8
>>23
あのね。。書けばそうなるってものじゃなくてそれを実装しなきゃならんのよ。。
コンパイラにそういったコンテクストを判断させるのがめちゃくちゃ難しいっていってるでしょ?
なんでそんなに読み取れないの?
あのね。。書けばそうなるってものじゃなくてそれを実装しなきゃならんのよ。。
コンパイラにそういったコンテクストを判断させるのがめちゃくちゃ難しいっていってるでしょ?
なんでそんなに読み取れないの?
26デフォルトの名無しさん
2021/04/27(火) 15:37:12.22ID:Nn42Sot02021/04/27(火) 16:10:45.63ID:/+bIFNU8
2021/04/27(火) 18:23:48.67ID:n/AWrch2
まあ半年後どうなるかで誰が正しかったかは分かるわな
2021/04/27(火) 20:32:29.92ID:/+bIFNU8
半年も経たなくてももうわかってるっつーの。。だからちゃんと英語の勉強しましょうね。
2021/04/28(水) 03:52:50.81ID:v8E9sca8
C++で、n要素のint型の生配列を確保するには、
int *pBuf = new int [n];
だけど、Rustの
let a:Box<i32> = Box::new<x>;
値が x である 32BIT 整数を Heap に 1 つ確保する、という意味だよね?
Heapに n 要素の i32 型の配列を確保したい場合、
let a:Vec<i32> = vec![0; n];
かな?
int *pBuf = new int [n];
だけど、Rustの
let a:Box<i32> = Box::new<x>;
値が x である 32BIT 整数を Heap に 1 つ確保する、という意味だよね?
Heapに n 要素の i32 型の配列を確保したい場合、
let a:Vec<i32> = vec![0; n];
かな?
2021/04/28(水) 03:55:12.80ID:v8E9sca8
>>30
あ、
let a:Box<i32> = Box::new<x>;
ではなく、
let a:Box<i32> = Box::new(x);
let a:Box<i32> = Box<i32>::new(x);
let a = Box::new(x);
let a = Box<i32>::new(x);
かな。
か
あ、
let a:Box<i32> = Box::new<x>;
ではなく、
let a:Box<i32> = Box::new(x);
let a:Box<i32> = Box<i32>::new(x);
let a = Box::new(x);
let a = Box<i32>::new(x);
かな。
か
2021/04/28(水) 04:01:18.27ID:v8E9sca8
>>31
確保した領域の中身を書き換えたい場合は「mut」を付ける必要があり、
値が x である 32BIT 整数を Heap に 1 つ確保するのは:
let mut a:Box<i32> = Box::new(x);
let mut a:Box<i32> = Box<i32>::new(x);
let mut a = Box::new(x);
let mut a = Box<i32>::new(x);
のどれかの書き方で、Heapに n 要素の i32 型の配列を確保するのが、
let mut a:Vec<i32> = vec![0; n];
let mut a = vec![0; n];
のどちらかの書き方かな?
確保した領域の中身を書き換えたい場合は「mut」を付ける必要があり、
値が x である 32BIT 整数を Heap に 1 つ確保するのは:
let mut a:Box<i32> = Box::new(x);
let mut a:Box<i32> = Box<i32>::new(x);
let mut a = Box::new(x);
let mut a = Box<i32>::new(x);
のどれかの書き方で、Heapに n 要素の i32 型の配列を確保するのが、
let mut a:Vec<i32> = vec![0; n];
let mut a = vec![0; n];
のどちらかの書き方かな?
2021/04/28(水) 10:37:51.57ID:6K8rF/jG
let mut a = Box::new([0,n]);
2021/04/28(水) 12:44:00.99ID:jQpDsyge
2021/04/28(水) 15:21:28.78ID:jQpDsyge
[0; n]
って、n 要素のi32配列を確保して0で初期化するという意味らしいけど、
nは実行時に決まらないような変数も指定できるの?
って、n 要素のi32配列を確保して0で初期化するという意味らしいけど、
nは実行時に決まらないような変数も指定できるの?
2021/04/28(水) 16:30:39.18ID:BfdKSrwu
>>35
できない
https://stackoverflow.com/questions/41710952/allocate-array-onto-heap-with-size-known-at-runtime
Vec<i32>に相当するのはstd::vector<int>だから、
>>33はstd::unique_ptr<int []>相当のBox<[i32]>型の例を出そうとしたのだろう
そういう値は作れるが、Box::newでは無理
できない
https://stackoverflow.com/questions/41710952/allocate-array-onto-heap-with-size-known-at-runtime
Vec<i32>に相当するのはstd::vector<int>だから、
>>33はstd::unique_ptr<int []>相当のBox<[i32]>型の例を出そうとしたのだろう
そういう値は作れるが、Box::newでは無理
37デフォルトの名無しさん
2021/08/31(火) 15:22:27.39ID:8qO1h2Cp 246 デフォルトの名無しさん sage 2021/08/31(火) 14:25:42.76 ID:SlncBcTV
>>244
ポインタは適切に使えばデータ構造やアルゴリズム自体が根本的に変えることが
できるので使わない時と比べて計算オーダー自体が劇的に変化することがあり、
プラシーボではない。
Rustはその点でC/C++に勝てない事がある。
247 デフォルトの名無しさん sage 2021/08/31(火) 14:28:10.16 ID:SlncBcTV
例えば、動的配列であるところのVectorはポインタでアクセスしても余り
効率は良くならないが、LinkedListは構造的にポインタで連結されており、
首尾一貫して添え字アクセスを使わずに必ずポインタでノードを識別する
ようにすれば、Vectorに比べて劇的に効率アップできることがある。
それはRustではほぼ不可能。ベンチマークはこの点が反映されてない。
>>244
ポインタは適切に使えばデータ構造やアルゴリズム自体が根本的に変えることが
できるので使わない時と比べて計算オーダー自体が劇的に変化することがあり、
プラシーボではない。
Rustはその点でC/C++に勝てない事がある。
247 デフォルトの名無しさん sage 2021/08/31(火) 14:28:10.16 ID:SlncBcTV
例えば、動的配列であるところのVectorはポインタでアクセスしても余り
効率は良くならないが、LinkedListは構造的にポインタで連結されており、
首尾一貫して添え字アクセスを使わずに必ずポインタでノードを識別する
ようにすれば、Vectorに比べて劇的に効率アップできることがある。
それはRustではほぼ不可能。ベンチマークはこの点が反映されてない。
2021/08/31(火) 16:19:11.51ID:KWeLtswn
コード例と性能測定結果くれ
2021/08/31(火) 17:18:36.26ID:SlncBcTV
>>38
同じ動作をしてもVectorだとO(N)なのに、LinkedListだとO(1)になるものがある。
これだけでも実験してみなくてもNが大きくなった時に明らかに速度が
違うことはコンピュータ科学では常識。
例えば、コロナの感染者数は、O(exp(aN))になるので、どんだけ頑張っても、
Nが十分大きい時にはO(N^b)が上回ることは出来ない。
同じ動作をしてもVectorだとO(N)なのに、LinkedListだとO(1)になるものがある。
これだけでも実験してみなくてもNが大きくなった時に明らかに速度が
違うことはコンピュータ科学では常識。
例えば、コロナの感染者数は、O(exp(aN))になるので、どんだけ頑張っても、
Nが十分大きい時にはO(N^b)が上回ることは出来ない。
2021/08/31(火) 18:26:05.32ID:8qO1h2Cp
まだstable入りはしてないけどlinked_list::{Cursor, CursorMut}っていうのがあるね
そのベンチマークでは使ってる?
そのベンチマークでは使ってる?
2021/08/31(火) 19:03:52.76ID:WFW0JNLV
LinkedListとはなんぞや?std::list?
2021/08/31(火) 19:52:34.92ID:4dUmDNFP
>>39
Rust は stable で LinkedList も VecDeque (双方向キュー)もありますよ
https://doc.rust-lang.org/std/collections/index.html
ここにそれらのオーダーが O(1) や O(N) になる話もまとまっています
Rust は stable で LinkedList も VecDeque (双方向キュー)もありますよ
https://doc.rust-lang.org/std/collections/index.html
ここにそれらのオーダーが O(1) や O(N) になる話もまとまっています
2021/08/31(火) 21:21:08.46ID:KWeLtswn
>>39
参照局所性の問題もあるから計算量の理論通りにはいかない場合もあるけど、ちゃんと性能測定してデータ構造選定した?
参照局所性の問題もあるから計算量の理論通りにはいかない場合もあるけど、ちゃんと性能測定してデータ構造選定した?
2021/08/31(火) 21:26:21.55ID:KWeLtswn
あとRustではほぼ不可能の意味が分からない
Rust にはポインタがあるから C や C++ のデータ構造はほぼ実現可能なのでは
Rust にはポインタがあるから C や C++ のデータ構造はほぼ実現可能なのでは
2021/08/31(火) 22:27:32.77ID:wvWDiazC
2021/08/31(火) 23:58:27.88ID:SlncBcTV
>>42
ところが、Rustでは借用規則のせいで上手く行かない。
めんどくさいので自分で気づく人だけが理解してくれればいいので、
俺はこれ以上説明しない。
理解できない人は、親切な人が説明してくれるのを待て。
ところが、Rustでは借用規則のせいで上手く行かない。
めんどくさいので自分で気づく人だけが理解してくれればいいので、
俺はこれ以上説明しない。
理解できない人は、親切な人が説明してくれるのを待て。
2021/08/31(火) 23:58:51.57ID:SlncBcTV
>>44
無理。
無理。
2021/09/01(水) 00:55:38.60ID:MtyAaHfZ
>>47
それはあなたが無知なだけだ
Rustはメモリ安全性を保証する
一方でRustの標準ライブラリではunsafeが多数使われているがこれはメモリ安全性を保証できる操作を効率よく実装するためにある
つまり論理的にメモリ安全性を保証できるならばunsafeを用いてもそれをライブラリやモジュールに閉じ込めることができる
もちろん自作でもこれは同様である
新たな型も当然作ることが可能
標準ライブラリで提供されているリンクドリスト型や双方向リスト型はそのようにして作られている
つまり効率をも落とさない
それはあなたが無知なだけだ
Rustはメモリ安全性を保証する
一方でRustの標準ライブラリではunsafeが多数使われているがこれはメモリ安全性を保証できる操作を効率よく実装するためにある
つまり論理的にメモリ安全性を保証できるならばunsafeを用いてもそれをライブラリやモジュールに閉じ込めることができる
もちろん自作でもこれは同様である
新たな型も当然作ることが可能
標準ライブラリで提供されているリンクドリスト型や双方向リスト型はそのようにして作られている
つまり効率をも落とさない
2021/09/01(水) 01:25:17.04ID:+dwouIiT
2021/09/01(水) 01:27:41.34ID:FA803rPU
>>40にも答えてくれよ
その「問題」とやらはCursorじゃ解決されてないのかい
その「問題」とやらはCursorじゃ解決されてないのかい
52デフォルトの名無しさん
2021/09/03(金) 08:12:39.26ID:t+NhPRD1 >>49
ガイジ
ガイジ
2021/09/07(火) 20:33:21.38ID:ezLxFpG4
結局unsafe多用するとか意味ないジャンw
54デフォルトの名無しさん
2021/09/07(火) 23:30:30.79ID:W5eU3b0C >>53 裏方のunsafeなコード(≠危険なコード)を安全に利用してプログラムを書けるのがRustだと思う
また、その裏方のunsafeなコードをRustで書く意味はRustから扱いやすいこと、Rustプログラマーが慣れたRustの文法で書けることがあると思う
また、その裏方のunsafeなコードをRustで書く意味はRustから扱いやすいこと、Rustプログラマーが慣れたRustの文法で書けることがあると思う
2021/09/08(水) 01:30:18.74ID:c9lCkxrV
2021/09/08(水) 01:30:55.64ID:c9lCkxrV
unsafeを閉じ込め切れるならRustはパーフェクトだが、そうはなってないのだ。
57デフォルトの名無しさん
2021/09/08(水) 09:53:24.22ID:8gtworgR >>55 そうか、まぁ一個人の感想ぐらいに受け取ってくれ
58デフォルトの名無しさん
2021/09/09(木) 16:53:30.53ID:lJRSMQ7p なんだかんだ言ってまだまだC++だな
2021/09/09(木) 17:22:38.75ID:fa/WJTRs
unsafe を閉じこめられるかどうかはAPI設計力が問われるよな
2021/09/09(木) 18:17:29.61ID:18O2MBOf
2021/09/10(金) 08:39:25.32ID:w07MHOd0
2021/09/10(金) 09:06:15.40ID:Ga+Uz44a
数学関係ないし
お前には数学の才能が無い
お前には数学の才能が無い
2021/09/10(金) 09:26:50.69ID:XIGB6bHM
数学的に間違いの意味がようわからんが、
unsafeブロック内あるいは関数内でSAFETYが守られるようにしないと安全に閉じ込めることができないって意味??
unsafeブロック内あるいは関数内でSAFETYが守られるようにしないと安全に閉じ込めることができないって意味??
2021/09/10(金) 09:28:15.95ID:KDfyX1FH
Vec<T> が unsafe を使って安全なインターフェースを提供してることへの反論を示してくれ
2021/09/10(金) 11:00:27.70ID:4cVpX4oe
>>63
そうでなくて、unsafeブロックで閉じ込めようとしても、閉じ込め切れなくて、
O(x)で表される計算時間が、C言語とは同じでは絶対に不可能な場合があるんだ。
Rustのsafeモードでは、コンテナの中のノードに対して書き込み参照と読み込み参照
を持つことが借用規則によって禁じられていることが原因。
C言語ではそれが当たり前に出来るからとても効率の良いプログラムが可能だが
Rustでは、unsafeの外側ではそれが出来ないから不可能だ。
アプリレベルでそれが出来ないから。
これで納得できない人は数学の才能が無い。
俺は数学の天才。
そうでなくて、unsafeブロックで閉じ込めようとしても、閉じ込め切れなくて、
O(x)で表される計算時間が、C言語とは同じでは絶対に不可能な場合があるんだ。
Rustのsafeモードでは、コンテナの中のノードに対して書き込み参照と読み込み参照
を持つことが借用規則によって禁じられていることが原因。
C言語ではそれが当たり前に出来るからとても効率の良いプログラムが可能だが
Rustでは、unsafeの外側ではそれが出来ないから不可能だ。
アプリレベルでそれが出来ないから。
これで納得できない人は数学の才能が無い。
俺は数学の天才。
2021/09/10(金) 11:05:19.78ID:4cVpX4oe
>>65
数学の才能が無い人のためにもう少し詳しく書いてやろう。
・Rustのsafeモードでは、LinkedListの中の複数のノードに対して、
読み込み参照と書き込み参照を一度自動時には持てない。
持つと borrow cheker がコンパイル時にエラーを出してしまう。
・C言語ではそれが当たり前に出来る。
・アプリレベルで1つのLinkedListに対して複数の読み込み参照と
書き込み参照を同時に記録し続けることで、やっと、挿入や削除が
O(1)になる。index 値で保持すると O(N)になってしまうから、
vector と同じ速度オーダーしか出ない(つまり、LinkedList本来の性能
が全く出せない。)
・結果、Rustは、Cより遅いプログラムしか出来ない。その遅さは、データが
多いとき、C言語に比べて1万倍でも100万倍でも遅くなる。
数学の才能が無い人のためにもう少し詳しく書いてやろう。
・Rustのsafeモードでは、LinkedListの中の複数のノードに対して、
読み込み参照と書き込み参照を一度自動時には持てない。
持つと borrow cheker がコンパイル時にエラーを出してしまう。
・C言語ではそれが当たり前に出来る。
・アプリレベルで1つのLinkedListに対して複数の読み込み参照と
書き込み参照を同時に記録し続けることで、やっと、挿入や削除が
O(1)になる。index 値で保持すると O(N)になってしまうから、
vector と同じ速度オーダーしか出ない(つまり、LinkedList本来の性能
が全く出せない。)
・結果、Rustは、Cより遅いプログラムしか出来ない。その遅さは、データが
多いとき、C言語に比べて1万倍でも100万倍でも遅くなる。
2021/09/10(金) 11:27:11.50ID:2Djs9W2b
>>66
コードで書いて
コードで書いて
2021/09/10(金) 11:30:01.67ID:4cVpX4oe
2021/09/10(金) 11:36:42.07ID:4cVpX4oe
>>68
本当は次のような知識も必要:
・リンクドリストの構造。
・リンクドリストの挿入、削除などの計算オーダーO(x)。
・計算オーダーの記号O(x)の意味。ビッグオー。ランダウの記号。
東大、京大の学部レベルの解析学(微分積分学)の本を見よ。
・index 値 = 基本は配列の添え字。0から割り振られた連番。
リンクドリストでは本来使わないが、Rustではノードの場所を覚えておくために
使わざると得ない。その場合、リンクドリストの先頭のノードを 0 番とし、
次のノードを 1, その次のノードを 2 のように表す。
しかしそうすると、リンクドリスとの M 番目の場所の参照を取得するのに
O(M)の時間が掛かってしまい、リンクドリストの効率の良さが台無しになってしまう。
・このことから、リンクドリストが遅いという誤解を生む状況になってしまっている。
本当は次のような知識も必要:
・リンクドリストの構造。
・リンクドリストの挿入、削除などの計算オーダーO(x)。
・計算オーダーの記号O(x)の意味。ビッグオー。ランダウの記号。
東大、京大の学部レベルの解析学(微分積分学)の本を見よ。
・index 値 = 基本は配列の添え字。0から割り振られた連番。
リンクドリストでは本来使わないが、Rustではノードの場所を覚えておくために
使わざると得ない。その場合、リンクドリストの先頭のノードを 0 番とし、
次のノードを 1, その次のノードを 2 のように表す。
しかしそうすると、リンクドリスとの M 番目の場所の参照を取得するのに
O(M)の時間が掛かってしまい、リンクドリストの効率の良さが台無しになってしまう。
・このことから、リンクドリストが遅いという誤解を生む状況になってしまっている。
2021/09/10(金) 11:38:10.81ID:2Djs9W2b
>>68
東大数学って何?
東大数学って何?
2021/09/10(金) 11:39:59.60ID:4cVpX4oe
>>70
高校生が灯台に入学するときに受ける東大の数学の試験のことだよ。
それが簡単に解けるくらいのやつに聞いてみろって事だ。
しかし、受験テクニックやパターン学習によって解ける様になったやつはダメだ。
高校生が灯台に入学するときに受ける東大の数学の試験のことだよ。
それが簡単に解けるくらいのやつに聞いてみろって事だ。
しかし、受験テクニックやパターン学習によって解ける様になったやつはダメだ。
2021/09/10(金) 11:49:52.37ID:2Djs9W2b
>>69
O(1) で i 番目の要素にアクセスできる safe な LinkedList 実装はある
https://docs.rs/chainlink/0.1.0/chainlink/struct.LinkedList.html
O(1) で i 番目の要素にアクセスできる safe な LinkedList 実装はある
https://docs.rs/chainlink/0.1.0/chainlink/struct.LinkedList.html
2021/09/10(金) 11:52:48.63ID:2Djs9W2b
2021/09/10(金) 11:53:08.66ID:FsmeH+FF
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=bc6e823f6a44e442aabd4d4882d3eb5a
Repeated 1 time(s), duration = 2.531µs
Repeated 10 time(s), duration = 4.661µs
Repeated 100 time(s), duration = 29.449µs
Repeated 1000 time(s), duration = 256.555µs
Repeated 10000 time(s), duration = 1.800129ms
Repeated 20000 time(s), duration = 3.273489ms
Repeated 50000 time(s), duration = 8.345219ms
Repeated 100000 time(s), duration = 16.454731ms
Repeated 200000 time(s), duration = 32.911471ms
Repeated 500000 time(s), duration = 83.993118ms
Repeated 1000000 time(s), duration = 166.193956ms
結構実行毎にゆれる感じはあるけど、おおむねO(1)じゃないですかね
Repeated 1 time(s), duration = 2.531µs
Repeated 10 time(s), duration = 4.661µs
Repeated 100 time(s), duration = 29.449µs
Repeated 1000 time(s), duration = 256.555µs
Repeated 10000 time(s), duration = 1.800129ms
Repeated 20000 time(s), duration = 3.273489ms
Repeated 50000 time(s), duration = 8.345219ms
Repeated 100000 time(s), duration = 16.454731ms
Repeated 200000 time(s), duration = 32.911471ms
Repeated 500000 time(s), duration = 83.993118ms
Repeated 1000000 time(s), duration = 166.193956ms
結構実行毎にゆれる感じはあるけど、おおむねO(1)じゃないですかね
2021/09/10(金) 12:09:20.46ID:4cVpX4oe
2021/09/10(金) 12:12:17.45ID:Ga+Uz44a
>>68
呼んだ?
呼んだ?
2021/09/10(金) 12:14:53.57ID:Ga+Uz44a
2021/09/10(金) 12:18:15.36ID:Ga+Uz44a
少なくとも>>65が書いてることは数学的でも何でもない
2021/09/10(金) 12:18:20.87ID:FsmeH+FF
2021/09/10(金) 12:27:50.85ID:4cVpX4oe
>>79
push_front()使ってるから先頭へ挿入してるだけじゃないか。
Cのリンクリストは、どんな非負整数 M に対して、M番目に挿入しても
MにもNにも依存しない定数時間で挿入できる。
それがRustに欠けている。
push_front()使ってるから先頭へ挿入してるだけじゃないか。
Cのリンクリストは、どんな非負整数 M に対して、M番目に挿入しても
MにもNにも依存しない定数時間で挿入できる。
それがRustに欠けている。
2021/09/10(金) 12:28:54.60ID:2Djs9W2b
>>75
そのオーバーヘッドは実用上問題になりますか?
例えばmallocの実装もarenaを使っていますが問題はないのですか?
そもそも計算量の議論をしていたのはあなたなのになぜ論点をずらすのですか?
そのオーバーヘッドは実用上問題になりますか?
例えばmallocの実装もarenaを使っていますが問題はないのですか?
そもそも計算量の議論をしていたのはあなたなのになぜ論点をずらすのですか?
2021/09/10(金) 12:30:48.00ID:Ga+Uz44a
2021/09/10(金) 12:41:50.91ID:4cVpX4oe
2021/09/10(金) 12:42:38.21ID:XIGB6bHM
>>65が何言ってるのか1行たりとも理解できなくて日本語の見た目した何かにしか見えないんだけど、
なんで話が進んでるの・・・
なんで話が進んでるの・・・
2021/09/10(金) 13:08:34.28ID:Ga+Uz44a
>>83
自分でM番目に挿入って書いてるわけだが
自分でM番目に挿入って書いてるわけだが
2021/09/10(金) 13:34:07.88ID:4cVpX4oe
>>85
「M番目に挿入」するが、それをMという数値で識別するとは書いてない。
数学とはそういうものだ。
ポインタ p で表現する場合でも、p が M 番目のノードを指していることがある。
その場合は、M番目に挿入と表現される。
そう表現しないと、O(x)記号で表現しにくいからだ。
「M番目に挿入」するが、それをMという数値で識別するとは書いてない。
数学とはそういうものだ。
ポインタ p で表現する場合でも、p が M 番目のノードを指していることがある。
その場合は、M番目に挿入と表現される。
そう表現しないと、O(x)記号で表現しにくいからだ。
2021/09/10(金) 13:35:00.70ID:FsmeH+FF
2021/09/10(金) 13:35:29.31ID:4cVpX4oe
数学での言葉の表現と日常の言葉の表現は異なる。
「M番目に挿入」することと、そのノードを、index = M - 1 で表すこととは
別の話だ。
「M番目に挿入」することと、そのノードを、index = M - 1 で表すこととは
別の話だ。
2021/09/10(金) 13:47:35.86ID:4cVpX4oe
>>87
同じノードを複数のCursor/CursorMutが参照している場合、1つの参照経由
でノードを削除した場合、別の参照がダングリング参照になるのを0コストで
防ぐ方法は無いはずだ。
静的解析が不可能で、時間や記憶域に何らかのオーバヘッドが必要となるはず。
同じノードを複数のCursor/CursorMutが参照している場合、1つの参照経由
でノードを削除した場合、別の参照がダングリング参照になるのを0コストで
防ぐ方法は無いはずだ。
静的解析が不可能で、時間や記憶域に何らかのオーバヘッドが必要となるはず。
2021/09/10(金) 14:16:45.03ID:4cVpX4oe
さらに、1つの LinkedListに対して、同時に2個以上の CursorMut を作ることは
出来ないはず。
出来ないはず。
2021/09/10(金) 14:18:55.00ID:iOAXb/4V
Cでリンクドリストの途中を直接ポインタで持っていると速いが
その途中が削除された場合にそのポインタは危険なポインタとなる
つまりCで記述しても何らかのコストをかけなければ安全に出来ない
つまりこの問題はどの言語であろうがコストゼロにすることは不可能
その途中が削除された場合にそのポインタは危険なポインタとなる
つまりCで記述しても何らかのコストをかけなければ安全に出来ない
つまりこの問題はどの言語であろうがコストゼロにすることは不可能
2021/09/10(金) 15:27:02.65ID:I2sJLr90
93デフォルトの名無しさん
2021/09/10(金) 15:44:47.65ID:EyQ85oMr すげぇバカ
2021/09/10(金) 15:45:34.73ID:XIGB6bHM
よくわからないけどこんなスレよりqiitaとかzennとかで記事書いたほうがいいと思う
2021/09/10(金) 17:06:16.82ID:lpjuAWj9
>>86
屁理屈
屁理屈
2021/09/10(金) 17:11:54.58ID:lpjuAWj9
どんな非負整数Mに対して
と自分で書いている
当然与える情報はMである
各Mに対応するポインタを保持するなら
挿入時にそのテーブルを更新しなきゃならないから
O(1)では出来ない
と自分で書いている
当然与える情報はMである
各Mに対応するポインタを保持するなら
挿入時にそのテーブルを更新しなきゃならないから
O(1)では出来ない
2021/09/10(金) 17:38:39.28ID:dS7angqs
>>96
Mを与える情報とは書いてない。
Mというものを使わないと、LinkedListとVectorで共通した議論が出来なく
なるから書いてるだけ。数学では良く使う論法。
つまり、Mは、議論の中で場所を特定するために用いているだけで、
プログラム中で用いているとは言ってない。
Mを与える情報とは書いてない。
Mというものを使わないと、LinkedListとVectorで共通した議論が出来なく
なるから書いてるだけ。数学では良く使う論法。
つまり、Mは、議論の中で場所を特定するために用いているだけで、
プログラム中で用いているとは言ってない。
2021/09/10(金) 17:41:20.99ID:dS7angqs
例えば、コンテナに100個のノードが入っていたとする。
コンテナは、LinkedListやVectorなどどんなアルゴリズムを使っているかは何でも良い。
で、「5番目の場所にノードを追加する」という言葉は、LinkedListにも使えるが、
その場合、プログラム中では5という数値で識別せず使わず、ポインタで識別する
のが C言語での常識。
でも、「5番目の場所に追加する」という言葉は使ってよい事になっている。
コンテナは、LinkedListやVectorなどどんなアルゴリズムを使っているかは何でも良い。
で、「5番目の場所にノードを追加する」という言葉は、LinkedListにも使えるが、
その場合、プログラム中では5という数値で識別せず使わず、ポインタで識別する
のが C言語での常識。
でも、「5番目の場所に追加する」という言葉は使ってよい事になっている。
2021/09/10(金) 17:43:19.62ID:iOAXb/4V
>>96
その人は数学が得意と言いながらそこすら理解できていない人だからね
Cでもプログラミングしたことあるならすぐわかることだからプログラミング経験も乏しいと推測される
つまりRustを叩きたいだけの人が暴れているだけの構図
その人は数学が得意と言いながらそこすら理解できていない人だからね
Cでもプログラミングしたことあるならすぐわかることだからプログラミング経験も乏しいと推測される
つまりRustを叩きたいだけの人が暴れているだけの構図
100デフォルトの名無しさん
2021/09/10(金) 17:48:47.41ID:dS7angqs >>99
理解してる。
お前らが、M番目のノードを数値Mでプログラムでも辿ると勘違いしている
抽象化が理解できない馬鹿だからそう思ってるだけ。
俺は抽象化が得意だから、M番目のノードをポインタで識別すると
考える。お前らは、Mとpを脳内で橋渡しできないだけ。
理解してる。
お前らが、M番目のノードを数値Mでプログラムでも辿ると勘違いしている
抽象化が理解できない馬鹿だからそう思ってるだけ。
俺は抽象化が得意だから、M番目のノードをポインタで識別すると
考える。お前らは、Mとpを脳内で橋渡しできないだけ。
101デフォルトの名無しさん
2021/09/10(金) 17:49:37.61ID:dS7angqs 数学的才能の無い人とは話が合わない。
知能に差が大きすぎる人達とは話が合わない。
知能に差が大きすぎる人達とは話が合わない。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 中国国営メディア「沖縄は日本ではない」… ★6 [BFU★]
- 外務省局長は無言で厳しい表情…日中の高官協議終了か 高市首相“台湾”発言で中国が強硬対応 発言撤回求めたか… [BFU★]
- 政府、株式の配当など金融所得を高齢者の医療保険料や窓口負担に反映する方針を固めた [バイト歴50年★]
- ナイツ塙が指摘のローソンコーヒーカップ、ロゴ「L」で誤解生みデザイン変更へ 在庫使い切る3か月後にリニューアル [muffin★]
- バービー、 台湾有事の発言の波紋で「たまったもんじゃない」「高市さんに真意は聞きたい」「国民に向けて説明してほしい」 [muffin★]
- 【速報】 高市政権、「日本版DOGE」を立ち上げ 米国で歳出削減をした「政府効率化省(DOGE)」になぞらえたもの [お断り★]
- 【悲報】日銀植田「利上げはデータ次第」と高市にぴしゃり [733893279]
- 日銀植田総裁「高市早苗と為替について議論、政府と連携して注視することで一致した」 [888298477]
- 【悲報】中国→日本行きの航空チケット、高市有事の影響で50万人分がキャンセルされる [834922174]
- 岸田文雄「国民は不安よな 岸田、動きます」 非核三原則堅持の立場示す [175344491]
- 【悲報】早速高市首相のせいで全国の民泊でキャンセルラッシュwwwwwwwwwwww 経営者も嘆き「こんな事は初めてだ…」😲 [871926377]
- んなっしょい🍬禁止🈲のお🏡
