Rust part15 ..
[2ch|▼Menu]
33:デフォルトの名無しさん
22/05/15 15:40:51.12 hZXiQ87C.net
教えてもらったsuccessorsを披露したくてしょうがない幼児メンタルwww
>>24の言う通りだな

34:デフォルトの名無しさん
22/05/15 15:49:35.48 AAncJnA8.net
>>33
successorsは適用範囲が非常に狭いので>>30の例には使えないはず

35:デフォルトの名無しさん
22/05/15 16:09:35.61 Cy+Jf1ha.net
>>33
ぜひそれを披露してやり方を教えてください

36:デフォルトの名無しさん
22/05/15 16:27:05.61 KYkY1Akn.net
フィボナッチ数列イテレータ前スレでだれかが書いてたでしょ
それじゃいかんの

37:デフォルトの名無しさん
22/05/16 07:04:42.44 nGMMRLLq.net
>>36
CopyやCloneを使っているから別問題だろう。
一般的にRustのプログラミングでは、
Copy(暗黙的な自動コピー)やClone(clone()による明示的な手動コピー)を使うと楽になるが、コストは高くなる。
そのため不要なclone()を見極めてそれを回避するプログラミングが出来るかどうか、というRustにおける根源的な話だろう。

38:デフォルトの名無しさん
22/05/16 07:28:24 JrfUQrzl.net
Copyのコストが高い?

39:デフォルトの名無しさん
22/05/16 08:00:50.97 nGMMRLLq.net
>>38
もちろんCopyは最もコストが高い。
個々のコスト自体は通常clone()と同じだが、常に自動的にclone()が起きるため最もコストが高くなる。

40:デフォルトの名無しさん
22/05/16 08:58:48.98 tFcB4vDN.net
複製おじさんはいつも自分勝手な妄想を「一般的には~」とか「皆は~」と言って自分を正当化しようとするよね

41:デフォルトの名無しさん
22/05/16 10:03:10.22 0DWo1Xps.net
>>40
間違いは誰にでもあるからまだいいんだが
指摘されても反省するどころかさらなる妄想を撒き散らすのがほんと迷惑

42:デフォルトの名無しさん
22/05/16 11:11:33 02kk6/+P.net
おじさん使いの人の自演がいつもよくわからん
唐突に妄想(?)を攻撃し出すが幻覚か何か見えてるのか

43:デフォルトの名無しさん
22/05/16 16:19:03.24 NE3SiQoq.net
>>39
Cloneのコストが高い型にCopyを実装するな

44:デフォルトの名無しさん
22/05/16 16:30:48.20 JLeK8lGd.net
Copyはコストが一番高いから出来る限り避けるべきだな
特にヒープを使うならCloneまでにしておくべき
可能ならばCloneも避けるべきだが

45:デフォルトの名無しさん
22/05/16 18:08:42.72 ThGcWJJo.net
Copyは所有権を複製するから最も高コスト(キリッ!!

46:デフォルトの名無しさん
22/05/16 18:10:04.46 ThGcWJJo.net
もはやどのレスもギャグにしか見えん
俺のしってるCopyとは確実に違う

47:デフォルトの名無しさん
22/05/16 18:38:28.59 qW5+0T97.net
今までで一番意味不明なこと言ってるな
Copyのコストが高いならmoveのコストはどうなるのよ

48:デフォルトの名無しさん
22/05/16 18:44:18.84 Mb2xQVjt.net
>>45
所有権に複製という概念はない
Copyをimplすると使われる時に値が自動的に複製される
そのためCopyは最も高コスト
>>46
君のレスがギャグにしか見えん

49:デフォルトの名無しさん
22/05/16 18:47:50.19 /5k6Bg80.net
Rust のムーブはビットパターンのコピーだもんな。
低レイヤの視点で見たらコピーと何の差も無い。
なるべく参照を使う場合にしても間接参照の実行コストとコピーの実行コストを天秤にかけてどちらが有利かは場合による。

50:デフォルトの名無しさん
22/05/16 18:55:12.38 W7mPHnnh.net
>>47
それは理解不足すぎるぜ
大文字のCopyはCopyトレイトを意味しCopyトレイトを実装するか否かの話だろ
moveは別方向の話であり比較対象にすらならない
比較するならば「Copy実装(必然的にClone)も実装」「Cloneのみ実装」「どちらも実装なし」の3つだな

51:デフォルトの名無しさん
22/05/16 19:00:08.16 GLqKLCqS.net
>>48
ギャグだと分からない人がいるとは想定していませんでした。
誤解を招いたのであれば申し訳ございません。

52:デフォルトの名無しさん
22/05/16 19:06:18.85 78bNbDCr.net
>>49
デタラメすぎ
ムーブでビットパターンのコピーは発生しない
ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
Copyのコピーはディープであって高コスト

53:デフォルトの名無しさん
22/05/16 19:08:38.74 NE3SiQoq.net
そもそもフィボナッチ数列イテレータなんて誰も求めてないので
前スレのだれかさんの実装に問題があると思うなら自分で勝手に改善してなさい
そしてその結果はここに貼らなくていいぞ

54:デフォルトの名無しさん
22/05/16 19:11:06.58 zgsMMZOB.net
「ヒープ使うならCloneまでにしとけ」
このセリフが一番刺さった

55:デフォルトの名無しさん
22/05/16 19:11:50.62 rHnqcaqs.net
>>52
おじさんマジかよwww

56:デフォルトの名無しさん
22/05/16 19:22:59.76 NE3SiQoq.net
>>54
Dropを実装する型はCopyを実装できないよ
BoxもRcもStringもVecもそもそもCopyを実装できないので、するかしないか考えること自体が無意味
どういう型にCopyを実装できるか、できないか、すべきかはdocsに書いてあるので
なんのかんの言う前にまずはこれを読もうね
URLリンク(doc.rust-lang.org)

57:デフォルトの名無しさん
22/05/16 19:37:56.79 tTdd7GU5.net
>>53
これだけCopyやCloneを理解していない連中が多い状況だと
>>30の質問に答えられるかどうかは最低限クリアすべきテストとして有用ではないか?
フィボナッチ自体はもちろんどうでもよい話だがCopyやCloneを避けるRustの基本ができるかどうかわかる点で

58:デフォルトの名無しさん
22/05/16 19:45:37.77 /5k6Bg80.net
>>52
じゃあムーブでなにが起こるとおもってんの?

59:デフォルトの名無しさん
22/05/16 19:54:25.89 SHnkjBGX.net
>>53
> フィボナッチ数列イテレータなんて誰も求めてない
それはそうなんだけど
唯一本人にとっては伝家の宝刀だから
少なくともこのスレいっぱいまでは引っ張って
何度も何度も参照するはず

60:デフォルトの名無しさん
22/05/16 20:38:11.38 NE3SiQoq.net
フィボナッチがどうでもいいならこの話は終わりです

61:デフォルトの名無しさん
22/05/16 20:45:13.08 Mz4z3EAu.net
関数の深いところから順に構造体をムーブで返していって
各関数で渡ってきた構造体のアドレスを表示させてみた
#[derive(Debug)]
struct S([i32; 100]);
fn main() {
let mut s1 = sub1(100);
s1.0[1] = 111;
println!("s1: {:p}", &s1);
println!("{s1:?}");
}
fn sub1(p: i32) -> S {
let q = p + 3;
let mut s2 = sub2(q);
s2.0[2] = p - 300;
println!("s2: {:p}", &s2);
s2
}
fn sub2(s: i32) -> S {
let t = s * 2;
let mut s3 = S([123; 100]);
s3.0[3] = t;
println!("s3: {:p}", &s3);
s3
}
s1もs2もs3もアドレスが一致
ムーブではアドレスそのままであり
ビットパターンのコピーが為されないという結論

62:デフォルトの名無しさん
22/05/16 20:58:36.88 qW5+0T97.net
>>50
"Copyのコストが高い" は Copy を実装する行為そのもののコストが高いと解釈すべきということ?
そんなばかな
>>52
ドキュメント読みましょうねー
URLリンク(doc.rust-lang.org)
> It’s important to note that in these two examples, the only difference is whether you are allowed to access x after the assignment.
> Under the hood, both a copy and a move can result in bits being copied in memory, although this is sometimes optimized away.
...
> The behavior of Copy is not overloadable; it is always a simple bit-wise copy.
...
> The implementation of Clone can provide any type-specific behavior necessary to duplicate values safely.
> For example, the implementation of Clone for String needs to copy the pointed-to string buffer in the heap.

63:デフォルトの名無しさん
22/05/16 21:06:43.52 qW5+0T97.net
>>61
アドレスが同じか否かでコピーの有無を判断する意味はよくわからんが
その理屈だとこのコードだと違うアドレスが表示されるからビットパターンのコピーがされてるって結論になるのか?
#[derive(Debug)]
struct S([i32; 100]);
fn main() {
let mut s1 = S([0; 100]);
println!("s1: {:p}", &s1);
let s2 = s1;
println!("s2: {:p}", &s2);
}

64:デフォルトの名無しさん
22/05/16 21:07:20.55 f/Xu02FO.net
>>61
struct S {}
fn main() {
let s1 = S{};
println!("s1: {:p}", &s1);
let s2 = s1;
println!("s2: {:p}", &s2);
}

65:デフォルトの名無しさん
22/05/16 21:08:00.98 f/Xu02FO.net
ごめん被った。やっぱそう思うよね。

66:デフォルトの名無しさん
22/05/16 21:16:19.81 9Ab93Lwf.net
>>56
ちょっとw
なんで刺さったのか少しは考えてよww
ギャグゴロシめ

67:デフォルトの名無しさん
22/05/16 21:19:28.47 51EzJkQ/.net
>>61
>>63
その二つの相異なる結果を見るとビットパターンのコピーはムーブ以外の要因で起きている??

68:デフォルトの名無しさん
22/05/16 21:30:56.46 W905eBh/.net
>>57
一番分かってないお前が言うなよw

69:デフォルトの名無しさん
22/05/16 21:38:19.38 /vD2A9J9.net
>>61
高コストなCopyも実装してから確認してみてねww

70:デフォルトの名無しさん
22/05/16 21:38:29.32 NE3SiQoq.net
>>66
ごめんよ
刺さったって「ためになった」みたいな意味で言ってるのかと思ったよ
てっきりオジの自演かと

71:デフォルトの名無しさん
22/05/16 21:39:12.01 DoCeaK1g.net
>>67
デバッグビルドだけじゃなくリリースビルドでも確認してねw

72:デフォルトの名無しさん
22/05/16 21:42:44.19 51EzJkQ/.net
>>71
リリースモードでもどちらも同じ結果

73:デフォルトの名無しさん
22/05/16 21:49:25.30 sElCPUyn.net
>>72
ごめんよー
>>64と間違えた

74:デフォルトの名無しさん
22/05/16 23:46:37.66 jfEIc0ZW.net
このスレはいつもおかしい人間たちが集まってるな
Rustの何が人を狂わせるんだ?

75:デフォルトの名無しさん
22/05/17 00:09:43.95 HbNyXd2X.net
おじさんイジリ飽きたので結論いっておく
Copyもmoveもスタックの中身をコピーしてるのは同じ
最適化によって不要なコピーが除去されるかどうかはLLVM次第
でかい配列やでかい構造体などの極一部を除けばCopyは参照の受け渡しよりも低コスト
ついでに言うと&TもCopy

76:デフォルトの名無しさん
22/05/17 00:26:01.61 +9bLcV37.net
>>75
頭悪すぎ
Copyが低コストなのではなく
低コストなものだけにCopyが実装されている
なぜならCopyは高コストであるため

77:デフォルトの名無しさん
22/05/17 02:09:56.03 2XRLgT14.net
>>76
ここでいうCopyのコストって具体的にどういう操作のコストのこと言ってる?
構造体データのbitwise-copyのこと?それとも別の何か?
Cloneやmoveの場合にそのコストは発生しないと主張しているの?

78:デフォルトの名無しさん
22/05/17 02:13:55.30 tAEVG8cC.net
>>62
ほーCopyってCloneの実装によらずmemcpy相当の結果になるのか
自動的に.clone()が差し挟まれる感じかと思ってた

79:デフォルトの名無しさん
22/05/17 07:41:41.18 1GDSnWAB.net
>>78
俺も同じくCopyは自動的にclone()されると思ってた
そう思ってた理由はClone実装せずにCopy実装するとエラーとなるため
そこで実験
#[derive(Debug,Copy)]
struct S { not_cloned: usize, cloned: usize }
impl Clone for S {
fn clone(&self) -> Self {
S { not_cloned: self.not_cloned / 3, cloned: self.cloned }
}
}
fn main() {
let s0 = S { not_cloned: 123, cloned: 456 };
let s1 = s0.clone();
let s2 = s0; // copy
println!("Cloned: {s1:?}");
println!("Copied: {s2:?}");
}
結果
Cloned: S { not_cloned: 41, cloned: 456 }
Copied: S { not_cloned: 123, cloned: 456 }
別物になった…

80:デフォルトの名無しさん
22/05/17 10:53:02 GxF458pr.net
>>52
>>>49
>デタラメすぎ
>ムーブでビットパターンのコピーは発生しない
>ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
>さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
>Copyのコピーはディープであって高コスト

このレス最強だな
一つ一つの文すべてが間違ってる
「デタラメすぎ」てw

81:デフォルトの名無しさん
22/05/17 14:50:42.61 94ESmIzZ.net
ガイジムーブ来てんね

82:デフォルトの名無しさん
22/05/17 21:03:27.69 VS5jQHYL.net
Copyはshallow copyだわな

83:デフォルトの名無しさん
22/05/17 22:07:44 LjbtS7tD.net
色々と正確な情報が出揃ったところで質問

まず前提として話を明白かつ簡単にするため、
ここでは!DropつまりCopy実装可能な型のみ対象、
そしてもしClone実装するならば*selfつまりCopy実装と同一、
CloneやCopyを実装するかどうかは任意、
小文字のcloneとcopyはそれぞれCloneやCopyを実装した時にそれらが使われることを意味するとする

このとき、次のどちらの主張が正しい?
A「copy/cloneはコストが生じるので、回避できるならば回避したほうが有利」
B「copy/cloneのコストはmoveと同じなので回避する必要はない」

84:デフォルトの名無しさん
22/05/17 22:30:37.28 VUKzLr9a.net
場合による。
たとえコピーであっても結局は内容が同じものであると看破すれば
実際にはコピーしないようなコードを生成するといったことは有りうる。
Rust は原理的にエイリアス解析がやりやすい言語だと思うし。
実行コスト的にどうかなんて考えずに所有権管理の側面からの妥当性で決めたほうがよい。
その上でどうしても実行コストを切り詰めないといけないようになったならその時に考えればいい。

85:デフォルトの名無しさん
22/05/17 22:33:27.98 5/60CrrJ.net
>>83
前提もまちがってるが
比較する対象がそもそも意味がない
もうちょっと勉強してから出直して

86:デフォルトの名無しさん
22/05/17 23:40:20.70 XaJZCLYj.net
>>83
>A「copy/cloneはコストが生じるので、回避できるならば回避したほうが有利」
何と比べてコストが生じると言ってるの?
回避した場合は何で代用するつもりなの?

87:デフォルトの名無しさん
22/05/17 23:43:19.03 nlEgMvZ6.net
考えてみたけどmove/copyが問題になるレベルの大きさの型をスタックに置いて扱ったことが無いな…
使うとすれば固定長配列のバッファ?
でもそんなものmove/copyするわけないし
やっぱり考える意味の無い二択だと思う

88:デフォルトの名無しさん
22/05/17 23:47:41.13 FqAlYuq2.net
>>86
回避する前と回避した後の比較だろう
回避したコードが書けたならばcopyの代用の必要はない

89:デフォルトの名無しさん
22/05/17 23:49:36.53 YviCLBk+.net
>>83
一般的にはAが正しい
ただし>>84が言うように無駄なコピーが消える場合もある
A「copy/cloneはコストが生じるので、回避できるならば回避したほうが有利になることがある」ならば


90:ウ確 Bについては前半はある意味正しいとしても後半が間違い >>85 批判や主張はその理由を伴わないと議論とならず意味がない



91:デフォルトの名無しさん
22/05/17 23:54:01.76 VUKzLr9a.net
>>89
> 批判や主張はその理由を伴わないと議論とならず意味がない
基本的にはそうだが、こっちが説明しても理解できるレベルに達してない場合にはどうせ議論にならんのでな。

92:デフォルトの名無しさん
22/05/17 23:55:13.39 tAEVG8cC.net
あっこの流れC++相談室で見たやつだ

93:デフォルトの名無しさん
22/05/18 00:07:06.58 P5Km+xQv.net
要は参照使えるなら使っとけって?
今更すぎませんか

94:デフォルトの名無しさん
22/05/18 00:30:37.66 DGffctwq.net
オナコードペタペタされてたほうがマシだったなこりゃ

95:デフォルトの名無しさん
22/05/18 00:45:17.78 opn2S8Zb.net
>>92
それもあるが、例えば多数のコピーが行われているコードに対して、回避できる分を見直し、少数のコピーで済むように改善できる場合もある
Copy実装せずに明示clone()した方が見つけやすいかもしれない

96:デフォルトの名無しさん
22/05/18 01:26:17.77 lxQ5l4ey.net
>>88
さすがに意味が分からないよ
値の受け渡しにcopyを使わないなら何が他の方法を使う必要があるでしょ

97:デフォルトの名無しさん
22/05/18 01:42:43.25 d5NnfCmB.net
一人だけ間違った思い込みをしてるのに
説明されても「俺は間違ってない、間違ってるのはお前ら」が続くだけだからな

98:デフォルトの名無しさん
22/05/18 01:46:16.75 6ezlEFaX.net
>>95
頭が硬すぎないか?
回避できる分を回避するだけだろ
回避できない分まで回避する、と思い込んてるのはYouのみ

99:デフォルトの名無しさん
22/05/18 01:51:55.82 Da/MVUm8.net
>>89
「○○はコストが生じるので、回避できるならば回避したほうが有利になることがある」
言葉の定義を明確にしないジェネリック文は
恣意的に常に真にも常に偽にもできる

100:デフォルトの名無しさん
22/05/18 02:06:14.30 UgigdTUo.net
>>90
無駄にプライド高いな
嫌われるぜ

101:デフォルトの名無しさん
22/05/18 07:08:20 bcZKOTNR.net
大きいフィールドを持つ型には、Copyは実装しないだろうし普通はCopy/Moveのコスト差を気にすることなくない?
どちらにすべきかボーダーが難しいことはありそうだけど

102:デフォルトの名無しさん
22/05/18 07:14:11 P5Km+xQv.net
>>94
データフローを見直して単純に消せるclone/copyは消せってことか?
それこそ今更すぎるわ
単純に消せないところまで消した後、さらにパフォーマンス改善するにはどうするかってことで、参照の話か?って聞いたんだけど

どこの誰とも知れないやつのフィボナッチのコードに対する指摘をされても知らねーよ
問題があって対策が分かってるなら自分で直すがいい

103:デフォルトの名無しさん
22/05/18 07:41:25.51 4GWzufxp.net
>>97
実行回数の話だったのかよww
まさかねw

104:デフォルトの名無しさん
22/05/18 07:56:39.00 HgdHe2aE.net
>>101
フィボナッチの件はBigIntなど非Copyも対象で今回の話は全く無関係だろ
そこを区別できていないのは相当ヤバいぞ

105:デフォルトの名無しさん
22/05/18 08:12:27.72 BE/QrV8J.net
流れからすると本当はジェネリックのフィボナッチにCopyを付けないほうが有利と主張したかったんじゃね?
でも後から回避できないことに気づいて苦しい言い訳を重ねてるだけと見た

106:デフォルトの名無しさん
22/05/18 08:21:27.45 6swlbHlO.net
>>85
根拠も示さず批判だけする一番アカン人間やな

107:デフォルトの名無しさん
22/05/18 08:33:04.08 6hDwlDoy.net
>>104
フィボナッチはCopyを回避できないものなの?

108:デフォルトの名無しさん
22/05/18 08:45:43.18 2HNq06l+.net
分からないなら分からないから教えてって言えばいいのに意地を張るからこうなる
構えば構うほど意味不明な発言が出てくる
真面目に議論したいならせめてIDコロコロ変えるのやめな

109:デフォルトの名無しさん
22/05/18 09:10:15.39 Gy2qdhBc.net
フィボナッチってこれだろ
f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2)
関数呼び出しに足し算に大量のコピーは避けられない

110:デフォルトの名無しさん
22/05/18 09:28:25.87 3vPi03ro.net
>>87
async関数やasyncブロックで生成されるFutureは結構大きくなることがあって、boxingした方が性能出るケースもある

111:デフォルトの名無しさん
22/05/18 10:05:07.09 jV65BxdQ.net
>>106
型制約からCopyを外すこことcopyを回避することは全く意味が違う
>>83の質問は明らかに後者
プリミティブも対象になるフィボナッチでcopyを回避するのは無理

112:デフォルトの名無しさん
22/05/18 10:20:40.09 AWXqkW+Q.net
>>110
型制約からCopyを外せばプリミティブと言えどもcopyされなくなる
具体的には個々のプリミティブ型へモノモーフィゼーゼーションされる前の段階でCopy実装していない型に対してのcopy発生エラーが生じる
フィボナッチでcopyを回避するのは可能

113:デフォルトの名無しさん
22/05/18 10:38:43.35 2JRtSvHV.net
複オジの主張まとめ(1)
37, 39, 44
=====
CopyやCloneを使っているから別問題だろう。
一般的にRustのプログラミングでは、
Copy(暗黙的な自動コピー)やClone(clone()による明示的な手動コピー)を使うと楽になるが、コストは高くなる。
そのため不要なclone()を見極めてそれを回避するプログラミングが出来るかどうか、というRustにおける根源的な話だろう。
もちろんCopyは最もコストが高い。
個々のコスト自体は通常clone()と同じだが、常に自動的にclone()が起きるため最もコストが高くなる。
Copyはコストが一番高いから出来る限り避けるべきだな
特にヒープを使うならCloneまでにしておくべき
可能ならばCloneも避けるべきだが

114:デフォルトの名無しさん
22/05/18 10:39:05.95 2JRtSvHV.net
複オジの主張まとめ(2)
50, 52, 57
=====
それは理解不足すぎるぜ
大文字のCopyはCopyトレイトを意味しCopyトレイトを実装するか否かの話だろ
moveは別方向の話であり比較対象にすらならない
比較するならば「Copy実装(必然的にClone)も実装」「Cloneのみ実装」「どちらも実装なし」の3つだな
デタラメすぎ
ムーブでビットパターンのコピーは発生しない
ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
Copyのコピーはディープであって高コスト
これだけCopyやCloneを理解していない連中が多い状況だと
>>30の質問に答えられるかどうかは最低限クリアすべきテストとして有用ではないか?
フィボナッチ自体はもちろんどうでもよい話だがCopyやCloneを避けるRustの基本ができるかどうかわかる点で

115:デフォルトの名無しさん
22/05/18 10:41:41.09 2JRtSvHV.net
複オジの一連の主張を読んでから>>83の複オジ質問を読むべし

116:デフォルトの名無しさん
22/05/18 10:44:21.46 Jso4/z1R.net
複おじに反応するやつも複おじ

117:デフォルトの名無しさん
22/05/18 10:52:26.71 j9G6SOiS.net
主張が毎回変わる
口調も毎回変わる
表記も毎回変わる
間違いなく多重人格者

118:デフォルトの名無しさん
22/05/18 10:55:48.57 TXrPyH7a.net
>>98
この文脈では○○にはなんでも当てはまるから意味がないよね
以下なら議論になる?
A「copy/cloneはmoveよりコストが生じるので、copyが必要な部分とそうでない部分で構造体を分離してでも出来るだけmoveを使用する」
B「copy/cloneのコストはmoveよりコストが生じるとは限らないので、一部でもcopyが必要な部分がある構造体は丸ごとcopyして構わない」

119:デフォルトの名無しさん
22/05/18 11:00:11.80 TXrPyH7a.net
>>116
そこまでいったらネット上では別人で良いだろ

120:デフォルトの名無しさん
22/05/18 11:05:55.27 f/6XNiB/.net
>>108
やってみた
fn main() {
for n in 0..100 {
let f = f(n);
println!("f({n}) = {f}");
}
}
fn f(n: i32) -> i32 {
match n {
0 => 0,
1 => 1,
n => f(n - 1) + f(n - 2),
}
}
このあたりから非常に重くなった
f(43) = 433494437
f(44) = 701408733
f(45) = 1134903170
f(46) = 1836311903
f(47) = -1323752223
f(48) = 512559680

121:デフォルトの名無しさん
22/05/18 11:24:29.81 Rx65yaNy.net
メモ化されてないんやから遅くなるのは当然
>>108は定義を示しただけちゃう?

122:デフォルトの名無しさん
22/05/18 11:25:30.07 Rx65yaNy.net
つかオーバーフローしとるな

123:デフォルトの名無しさん
22/05/18 11:29:30.10 e0i+LLok.net
>>119
そのコードだとcopyは何回くらい発生してるのだろう
0回?1回?2回?3回?たくさん?

124:デフォルトの名無しさん
22/05/18 12:13:31 QV9C5cPM.net
ぼくのかんがえたさいきょうのcountup<T>()をみんなバカにしたので
ぼくのかんがえたさいきょうのfibonacchi<T>()でやっつけようとしたら
わざをだすまえにボコボコにやられてしまいました
く、くやしいです!

125:デフォルトの名無しさん
22/05/18 13:41:52 mX15beFi.net
clone()が一個でコンパイル通ったからそのコードでのコピーは一回ではないか

use std::ops::{Add, Sub};
fn f<T>(n: T) -> T where T: Clone + PartialEq + TryFrom<usize> + Add<Output=T> + Sub<Output=T> {
let [zero, one, two] = [0, 1, 2].map(|n| T::try_from(n).ok().unwrap());
match n {
n if n == zero => zero,
n if n == one => one,
n => f(n.clone() - one) + f(n - two),
}
}

126:デフォルトの名無しさん
22/05/18 13:50:00 FQ8O/3lA.net
>>119
計算量はO(n), メモリ使用量は定数オーダーにできるのになんで定義どおり実装したの?

127:デフォルトの名無しさん
22/05/18 14:41:04.77 xTux5YG/.net
>>123
ぼくのかんがえたさいきょうのfizzbuzz<T>()もわすれないで

128:デフォルトの名無しさん
22/05/18 15:04:45.49 dI/aN4vs.net
>>125
そんな魔法はありません

129:デフォルトの名無しさん
22/05/18 16:48:40.40 pQAvghMm.net
>>127
え?

130:デフォルトの名無しさん
22/05/18 17:53:48.13 jsK0MVuh.net
Rust以前の問題じゃん
スレ違い

131:デフォルトの名無しさん
22/05/18 23:22:25.69 z2ufbs5N.net
>>124
そのclone()は子のf(n-1)とf(n-2)やそれらの子孫でも呼ばれるので1回ではなくO(n)より大きい
それをO(n)すなわちn回+定数回以下に抑えられるのかどうか
あるいはO(0)回すなわち定数回以下に抑えられるのかどうか

132:デフォルトの名無しさん
22/05/18 23:41:48.24 RLh6XGtQ.net
フィボナッチはu128を使ってもf(187)でオーバフローするからBigInt必須
clone()はできる限り少なくしないと厳しい

133:デフォルトの名無しさん
22/05/19 00:10:47.96 SnnzWk5R.net
どうでもいいから複おじはTRPL読み直してきてね

134:デフォルトの名無しさん
22/05/19 00:16:28.52 IEr5OW/T.net
>>120
メモ化したら速くなったけど
memoをこちらで用意して毎回渡していくのを避けられないのかな?
fn main() {
let mut memo: Vec<usize> = Vec::new();
for n in 0..100 {
let f = f(n, &mut memo);
println!("f({n}) = {f}");
}
}
fn f(n: usize, memo: &mut Vec<usize>) -> usize {
if let Some(result) = memo.get(n) {
*result
} else {
let result = match n {
0 => 0,
1 => 1,
n => f(n - 1, memo) + f(n - 2, memo),
};
memo.push(result);
result
}
}

135:デフォルトの名無しさん
22/05/19 00:24:17.53 d4KplWCH.net
メモ化する必要ある?
直前の2つだけ記録しておけば次の一項が計算できるんだから再帰にする必要ないよね

136:デフォルトの名無しさん
22/05/19 00:33:12.40 IEr5OW/T.net
>>134
具体的にどうすればよいてすか?

137:デフォルトの名無しさん
22/05/19 00:46:08.98 HY3grr6d.net
>>135
"rust fibonacci"でググるとよいです

138:デフォルトの名無しさん
22/05/19 01:21:23 f3pwm4rC.net
>>134
直前の2つだけ記録して再帰にしない方法ならば
おそらくこうする案だと思うが
>>133がO(n)で済んでいるのに


139:対して これは二重のforによりO(n^2)になっていてこれは悪手 fn main() { for n in 0..100 { let f = f(n); println!("f({n}) = {f}"); } } fn f(n: usize) -> usize { match n { 0 => 0, 1 => 1, n => { let mut prepre = 0; let mut pre = 1; for i in 2..n { let tmp = pre; pre += prepre; prepre = tmp; } pre + prepre }, } }



140:デフォルトの名無しさん
22/05/19 01:31:14.77 d4KplWCH.net
>>135
fn main(){
for n in 0..10{
println!("f({}) = {}", n, f(n));
}
}
fn f(n:usize) -> usize{
let mut a = 0;
let mut b = 1;
for i in 0..n{
let tmp = b;
b = a + b;
a = tmp;
}
return a;
}
わざわざRustっぽい書き方をする必要はない

141:デフォルトの名無しさん
22/05/19 01:39:04.90 f3pwm4rC.net
>>138
それもforが二重となっていて全体でO(n^2)だから同じく悪手

142:デフォルトの名無しさん
22/05/19 02:09:27.74 XQuKTBpO.net
>>131
なら尚のことジェネリックにする意味ないよね?

143:デフォルトの名無しさん
22/05/19 03:45:23.95 jyObMdH0.net
>>137,139
悪手ってなにをもって悪手だよ
一般項の導出は高校生でもできるレベルで、そうすればO(log(n))で求められるし、つまらん計算量改善のためだけのアルゴリズム議論はもうやめろ
これ以上計算量の話をするなら別のスレでやってくれ

144:デフォルトの名無しさん
22/05/19 04:01:44.79 f3pwm4rC.net
>>141
mainに既にforループがある
だから個々をO(n)で求めると全体でO(n^2)となる
もし個々をO(log(n))で求めたとしても全体でO(n✕log(n))となる
一方で>>133は優れていて全体でO(n)だから圧倒的に良手

145:デフォルトの名無しさん
22/05/19 08:08:36.85 SnnzWk5R.net
まあ(usize) -> usizeのインターフェースを持たせつつ逐次処理したければメモ化が楽だわな
Rustとは特に関係の無いアルゴリズム一般論の話だけど

146:デフォルトの名無しさん
22/05/19 12:20:27.39 TVQgVkXp.net
なんでmainのループまで計算量に入れてるの?
今やってるのはフィボナッチ数列の計算量の話でしょ
余計なところまで話し広げてどうするの?

147:デフォルトの名無しさん
22/05/19 12:42:29.01 Y0RaHe9J.net
いい加減こんな語り尽くされた話終わってろ
何スレだよここ

148:デフォルトの名無しさん
22/05/19 12:44:11.02 2eGzkY/T.net
>>143
メモ化は良いが>>133のコードはインターフェースがあまりよくない
逆に>>138のコードはn個の列挙にO(n^2)も費やしている
以下のように書けばn個の列挙がO(n)に収まり、個別f(n)もO(n)で両立できる
fn main() {
println!("f(77) = {}", f(77));
for (n, f) in fibonacci_iter().enumerate() {
println!("f({n}) = {f}");
}
}
fn f(n: usize) -> usize {
fibonacci_iter().nth(n).unwrap()
}
fn fibonacci_iter() -> impl Iterator<Item=usize> {
let mut p = 0;
let mut q = 1;
std::iter::from_fn(move || {
let r = p;
p = q;
q += r;
Some(r)
})
}

149:デフォルトの名無しさん
22/05/19 12:47:27.97 wYj4kQtM.net
僕チンすごい!ってホルホルしたいんだろうけど
脳のワーキングメモリーが減ってこの程度の内容でしかコードが書けないんだろうな

150:デフォルトの名無しさん
22/05/19 13:06:09.75 TVQgVkXp.net
まず計算量にmainのループを勘定してる時点で…

151:デフォルトの名無しさん
22/05/19 13:18:54.57 u56F2Ocx.net
>>144
> 今やってるのはフィボナッチ数列の計算量の話でしょ
その通りでアンタが正しい
>>148
フィボナッチ『数列』の計算量だから
mainのループを勘定するのは当然
f(0)、f(1)、f(2)、…、f(n)がフィボナッチ『数列』

152:デフォルトの名無しさん
22/05/19 18:50:45.11 j8hvvms1.net
イテレーターにするとメリット多いんだな
Rustと相性いい

153:デフォルトの名無しさん
22/05/19 19:01:17.07 SnnzWk5R.net
>>146はメモ捨ててるから計算済みのf(n)引っ張ってくるのに毎回O(n)かかるけどね
イテレータと相性良いように見えるとしたら0..nループと組み合わせることしかしてこなかったmainが見せる幻想
そろそろRustの話に戻ってもらっていいですか?

154:デフォルトの名無しさん
22/05/19 19:56:30.02 X9gr9ket.net
>>151
マジで>>133のメモ化が好ましいと思っているのか?
イテレータはメモ化とも相性が良い
例えば>>146のfibonacci_iter()を含むイテレータ汎用メモ化は即席でこんな感じ
fn main() {
let mut memo = IterMemo::new(fibonacci_iter());
assert_eq!(memo.nth(10), Some(55));
assert_eq!(memo.nth(0), Some(0));
assert_eq!(memo.nth(30), Some(832040));
assert_eq!(memo.nth(5), Some(5));
assert_eq!(memo.nth(50), Some(12586269025));
}
struct IterMemo<I> {
iter: I,
memo: Vec<usize>,
}
impl<I: Iterator<Item=usize>> IterMemo<I> {
fn new(iter: I) -> Self {
IterMemo { iter, memo: Vec::new() }
}
fn nth(&mut self, n: usize) -> Option<usize> {
for _i in self.memo.len()..=n {
if let Some(x) = self.iter.next() {
self.memo.push(x);
}
}
self.memo.get(n).cloned()
}
}

155:デフォルトの名無しさん
22/05/19 21:07:44.82 wYj4kQtM.net
汚いな

156:デフォルトの名無しさん
22/05/19 21:11:33.57 +7PnyNeM.net
複オジは何が問題だと指摘されてるのか理解しないんだよなぁ
頭悪いのにとにかくマウントだけ取りたがって恥の上塗り上塗り上塗り
何回塗るねんっw

157:デフォルトの名無しさん
22/05/19 21:20:54.65 5LQoe3Bs.net
ほらなw
ぼくのかんがえたさいきょうのひぼなっちいてれーた!
どや!? どやどやどや!!?
これで1000まで行くよw

158:デフォルトの名無しさん
22/05/19 21:27:22.70 SnnzWk5R.net
どうしてもイテレータが欲しいなら>>133に建て増ししたほうがよっぽど整理されていいよ
URLリンク(play.rust-lang.org)

159:デフォルトの名無しさん
22/05/19 21:29:51.14 u7/IlrFk.net
>>152
イテレータの規約に反したオレオレnth()はやめてくれ
IterMemoなんて名前の構造体にnth()が実装されてればイテレータのnth()と勘違いしてしまう

160:デフォルトの名無しさん
22/05/19 21:34:02.60 wYj4kQtM.net
その前に単純にバグ入りだけど

161:デフォルトの名無しさん
22/05/19 21:51:56.08 MGh63lg3.net
メモ化と個別機能が完全に分離できている>>152の方が良さげ

162:デフォルトの名無しさん
22/05/19 21:55:11.08 wYj4kQtM.net
このスレだけでなくRust書く人間はコケ前提なのが馬鹿らしい
未知の計算するのに対策してない馬鹿野郎ども

163:デフォルトの名無しさん
22/05/19 21:56:15.85 wYj4kQtM.net
目が覚めろ
目が覚めろ
コケ前提は恥ずかしい

164:デフォルトの名無しさん
22/05/19 21:56:34.11 iLpWQ9zs.net
>>159
分離できてねーよw
アホだろ
イテレータ使ったことないのか?

165:デフォルトの名無しさん
22/05/19 21:58:30.11 wYj4kQtM.net
Rust書く人間はレベルが低いと思われても平気なのか?

166:デフォルトの名無しさん
22/05/19 22:05:28.50 +v1Fmw4c.net
>>156は普通にフィボナッチ数列を順に表示するだけでも常にVecを使ったメモ化を伴うので筋がよくない
>>152はメモ化を付け外し可能で問題点も特に無いようだが

167:デフォルトの名無しさん
22/05/19 22:13:58.00 G2OEvBhv.net
「Rustでドヤりたい素人が犯しがちな12の過ち」
みたいな記事が捗りそう

168:デフォルトの名無しさん
22/05/19 22:18:44.85 iQApRYmM.net
>>164
関数の設計ができない人の発想

169:デフォルトの名無しさん
22/05/19 22:22:18.18 z7fdj+fO.net
>>164
なんでIDコロコロ変えてるの?

170:デフォルトの名無しさん
22/05/19 22:27:10.61 2ZXoSlQ2.net
>>165
複オジ特有の妄想を一般化するなよ
「複オジがドヤ顔で晒した恥ずかしい勘違い12選」にしとけ
需要ないけどな

171:デフォルトの名無しさん
22/05/19 22:29:47.42 EaXeIbDt.net
こんな数列ごときでヒープ必須の>>156はプログラミングが下手

172:デフォルトの名無しさん
22/05/19 22:47:12.76 AQMm07Qd.net
数列ごときのプログラムしか書けない複製おじさん……

173:デフォルトの名無しさん
22/05/19 23:33:01.93 wYj4kQtM.net
cargo run --releaseで予測した動きをしないコードを書くなよ
速やかにバグを取れ


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

30日前に更新/296 KB
担当:undef