前スレまでのあらすじ
---
987 デフォルトの名無しさん sage 2022/01/27(木) 17:14:15.89 ID:hWkHkx2k
>>986
> だから専有機なら上限で用いる
「現在の主流」というのは、「専有機」での話?
それとも一般的な話?
994 デフォルトの名無しさん sage 2022/01/27(木) 17:52:30.63 ID:LojT3k5n
自分が理解できないと相手が敵かつ全て同一人物に見える病気のパターンかねw
皆普通に同じことを指している
何が理解できないのか素直に言ってごらん
995 デフォルトの名無しさん sage 2022/01/27(木) 17:55:13.00 ID:hWkHkx2k
>>994
>>987の質問に答えてから続けてね 彼はこの部分がわからなくて連投していたみたいだから横から補足説明しましょう
> 大雑把にI/O観点で二つに分けると
> 昔は同期I/Oでブロックされるからマルチスレッド
> 今は非同期プログラミングでスレッド数はシングルからCPUコア数が上限
> RustのFutureタスク、GoのGoルーチン、JavaScriptの非同期Promiseやコールバック
> いずれもプロセス内スケジューラがI/O多重化(select/epoll)やタイマーなど管理して非同期プログラミングを支えている
昔は自分でOSスレッドを立ち上げて使っていたのに対して
今は自分で立ち上げるのがOSスレッドではなくそれよりも粒度が細かく軽い非同期なタスクで
OSスレッドを立ち上げる役割はそれらタスクの非同期なスケジューリングをするランタイムで
そのスレッド立ち上げ個数は効率最大のためCPUコアスレッド総数と一致するのが望ましいため
GoやRustなどではデフォルト値がそうなっていますよってことですよね
もちろん個数を1個つまりシングルスレッドに設定しても動くところが決定的な違いですね
OSがスケジューリングしてくれるけど重くて大きくリソースを喰うOSスレッドを今は直接使わずに
> RustのFutureタスク、GoのGoルーチン、JavaScriptの非同期Promiseやコールバック
これらのもっと軽くて小さなタスクを使うことで何万も同時に処理できるようになったという話ですね
ちなみにRustでは昔と同じ状況にスレッドとタスクを1:1(=n:n)でも使えますし
シングルスレッドにして1:nでも使えますし上述の状況は汎用的なm:nになりますね
明らかに間違ってることを自信ありげに語るのはいつものこと
その人達用の隔離スレだから
>>1乙 次はgoogleで2件しかヒットしない、「プロセス内スケジューラ」については説明してくれw
非同期タスク群のスケジューリングをするランタイム部分のことではないでしょうか
一般的にプロセスの中に1つだと各スレッドへタスクを割り振るコストが高くて
各スレッドの中に独立して1つずつだと暇なスレッドと多忙なスレッドが偏るデメリットがあり
GoでもRustでもそれらのスケジューリング問題を改善するために
各スレッド内に独立キューを持って効率的に処理しつつもグローバルキューも備えることで解決しているようですね
複製おじはGoでもRustでもまともに非同期プログラミングやったことないんだな
>>8
OSスレッドがOSによりスケジューリングされることに対する対比じゃね?
タスクは各プロセスの中にスケジューラーがある
Goは言語ランタイムの中だがRustは各自が好きなのを選んだり自作も可能 どうせRustは普及しないんじゃないかな、知らんけど。
rustはc++を食うことがあってもピュアcを食うことはなさそう
Cは誤解を恐れずに言えばアセンブリ言語みたいなもんだからな
>>13
C++ 98以前は Cと似てるし、ライブラリも言語とは無関係に自由に作れたから大丈夫。C++11以後はダメ言語になった。 そもそも、CやC++が普及したのはTurboCのおかげ。
TurboCはライブラリが分かり易かった。
C++11以後、言語もSTLも両方腐っていてTurboCとは全く違うようになり、
人気もがた落ちになった。
>>8
OSによるプロセスやOSスレッドのスケジューラではなく
プロセスの中で動くタスクのためのスケジューラ
各言語によって言語機能として備えている場合と外部ライブラリによる場合がある
Rustではその中間の形態で言語機能としてはasync/awaitの枠組みのみ提供
さらに標準ライブラリとしてFutureやWakerなどの必要とする定義のみ提供
実際に動作するスケジューラは外部ライブラリで様々な提供がなされ自作もできる
その他はこのスライドの前半の解説など参照
Rustのasync/awaitとスケジューラの話
https://speakerdeck.com/osuke/rust-async-await 前スレ946の三つのサイトから数値を入手して和を求める例を練習のためにやってみたんだが
httpのheader取得までとbody取得の2回awaitが入るのがなるほどと思った
あと文字列を数値に変換parseも当然必要だったのでawait部分がちょっと長い
#[async_std::main]
async fn main() -> surf::Result<()> {
let n1 = surf::get("https://httpbin.org/base64/MTEx"); // 111
let n2 = surf::get("https://httpbin.org/base64/MjIy"); // 222
let n3 = surf::get("https://httpbin.org/base64/MzMz"); // 333
let sum = n1.await?.body_string().await?.parse::<i32>()?
+ n2.await?.body_string().await?.parse::<i32>()?
+ n3.await?.body_string().await?.parse::<i32>()?;
assert_eq!(666, sum);
Ok(())
}
利用させてもらったテストサイトはURLで返す値など指定できるhttpbin.org
これで動いて値取得もできて合計値assertも通ったのだが実は落とし穴があることに気付いた 元のJSのコードもだけど
await連発すんなよw
そのテストサイトにhttp返答を遅延させるdelay機能があるので試した時に露見した
同時に指定値を返せないようなので数値化と足し算の意味はないが遅延時間を知りたかった
let d1 = surf::get("https://httpbin.org/delay/4"); // 4秒
let d2 = surf::get("https://httpbin.org/delay/5"); // 5秒
let d3 = surf::get("https://httpbin.org/delay/3"); // 3秒
let sum = d1.await?.body_string().await?.parse::<i32>().unwrap_or(0)
+ d2.await?.body_string().await?.parse::<i32>().unwrap_or(0)
+ d3.await?.body_string().await?.parse::<i32>().unwrap_or(0);
結果は12秒かかってしまい期待と異なり直列に実行されていた
肝心なことを忘れていた JavaScriptではPromiseを返す関数を3つ呼べばそれで3つ並行に実行される
しかしRustでは並行に動くタスクを自分で明示的に起動しなければいけなかったのだ
よく考えればGoでも自分で明示的にgoと前置指定することで別goルーチンを起動している
Rustではそれがspawnでありgoと同じくそれによりスケジューラに登録されるようだ
use async_std::task::spawn;
let d1 = spawn(surf::get("https://httpbin.org/delay/4")); // 4秒
let d2 = spawn(surf::get("https://httpbin.org/delay/5")); // 5秒
let d3 = spawn(surf::get("https://httpbin.org/delay/3")); // 3秒
このようにspawnを付けて以降は同じ実行をすると全体で結果5秒となり並行に実行された
言語自体に魔法の仕組みはなく自分で明示的にスケジューラに登録指定するのはわかりやすくて安心した
そのスケジューラも手作りできるらしく興味深い 自分でblock_on書かないとRustのasyncは身に付かない
>>23
use async_std::task::{block_on, spawn};の時
このblock_onを使った
fn main() -> surf::Result<()> {
block_on(async {
let d1 = spawn(surf::get("https://httpbin.org/delay/4"));
// 略
})
}
の簡略版が>>19で書いた
#[async_std::main]
async fn main() -> surf::Result<()> {
let d1 = spawn(surf::get("https://httpbin.org/delay/4"));
// 略
}
ってことか
つまりasync { ... } という非同期ブロックをblock_onによりスケジューラに実行させているわけだ
当たり前だがspawnする以前に最初からスケジューラの掌の上で踊っていたのであった
じゃないと全体を並行に実行できないもんな Rustのasync/awaitはコンパイルされると単純なステートマシンになる
例えばasyncブロック内にfuture1.awaitとfuture2.awaitが順に呼び出されるとする
最初はfuture1をpollする状態でpending中はpendingを返す
そこでreadyになればfuture2をpollする状態へ遷移
そこでもreadyになれば全体としてreadyを返す状態へ遷移
結局スタックレスなコルーチンを実現しているだけなので非常に軽い
起動も切替もスレッドより軽くてリソースも喰わないなら
非同期タスクの欠点は何だ?
Rustの場合軽量タスクはプリエンプティブじゃないので、変なコーディングすると特定のタスクが実行され続けて、他のタスクがいつまでも実行されないことがある
あとは、OSのスレッドじゃないからスレッドの属性や権限をタスク単位で異なる物にすることはできないとか
>>27
前者は間違えて同期ブロッキングする関数を呼んでブロックしてしまった場合
および長時間ずっと全く非同期関数を呼ばずに計算し続けるか暴走する場合
これらはバグならfixで解決
バグでないなら非同期タスク実行スレッドとは別に専用スレッドを用意して実行できるスケジューラもあるのでそれを利用 >>28
同じ処理でも入力内容次第で変わるからそんな簡単にいかないよ async-stdならgoみたいにタスクが一定時間経っても制御返してくれないときに勝手にスレッド起こしてくれるんじゃなかったっけ
>>29
入出力が行なわれたらタスクのスイッチングが発生するので
意図的にブロッキングするものを呼んでブロックしているケースを除くと
いつまでもタスクが切り替わらないのは演算のみを延々と続けるケースのみになる
対応策としては自分で定期的に手放すか以下の方法で回避
>>30
それは様々な問題点で中止
結局tokioもasync_stdもそのような特殊ケースはspawn()の代わりにspawn_blocking()することで
タスクのスイッチングに影響が出ないように別スレッドで実行させる方針
その場合は結局スレッドを自分で起動して同期ブロッキングで使う昔からの方法と実質同じだが
そのような特殊なケースも含めて統一的にタスクを扱える そのbudget方式は戻ってこないとペナルティ与えられないから本質的な解決になっていない
yield相当をコンパイラが上手く挟むのも無理だからプログラマーが自らすればいい
歴史ってのがマルチタスクOSにおける cooperative vs preemptive の話だとするなら前提が違いすぎない?
任意のアプリケーションが動く可能性のあるOSと自身のプログラムのルーチンが実行されるアプリとではスケジューラに求められる制約条件は違って然るべきかと
シングルスレッドかつcooperativeなJavaScriptがNode.jsを含めて成功しているように問題なく動作する
同期ブロッキングを完全排除してしまえばタスク切り替えが起きない場合すなわちスケジューラに戻らない場合は
入出力もなくループでメモリ上演算を繰り返している場合となる
そのような場合でもループ内で自分で定期的にスケジューラへ制御を戻してやればよい
そのためにRustではtask::yield_now()がある
イベントループがハングアップした時の対処とか考えたことないでしょ?
バグだからfixすればいいじゃ能がない
歴史に学ぶといいよ
>>37
GoやJavaScriptなどは言語内蔵だが問題が起きたことはない
Rustは言語から切り離されているが同様
いずれもそれらのランタイムの製作者以外がその部分のコードを触ることはなくバグが発生しようがない >>37
> イベントループがハングアップした時の対処とか考えたことないでしょ?
そういうのは上位で対処(タイムアウトでプロセス再起動とか)することもあるからケースバイケースでしかない イベントループがハングアップするってなに?
epoll_waitをブロッキングで使う場合でもタイムアウト設定すればハングアップなんてしないでしょ?
タイムアウト設定忘れみたいなバグの話でしょ
そんなに引っ張る話でもないと思う
>>41
それは万が一あるとしても非同期スケジューラランタイム実装者の管轄
その利用者である一般プログラマーが引き起こすバグではないため関係ない > epoll_waitをブロッキングで使う場合でもタイムアウト設定すればハングアップなんてしないでしょ?
の話だぞ?
歴史って言葉持ち出してるんだしそんなしょうもない話じゃなくてもっと有名なエピソードなんじゃないの
「Rustのタスクの欠点は?」
「プリエンプティブじゃないところ」
「プログラマーが注意すればいいだけだから問題ない」
そりゃepollやselect相当を自分で使っていてミスをすればイベントループがハングアップするのは当たり前
しかし非同期タスクのイベントループは非同期スケジューラの中にあって自分でepollやselectを扱わなくてよくなった
だから自分のミスでイベントループがハングアップすることはなくなった
それ以前の歴史では色々あったが状況が変わった
はいはい、理想的な環境で羨ましいですね
これでいいかな?w
メモリ開放忘れみたいなバグの話でしょ
そんなに引っ張る話でもないと思う
バグ耐性高めるためにタスクをプリエンプティブにしたいならすれば良いのでは
プログラマーのスタンスに合わせて適切な物を選べるよう選択肢は用意されてると思うが
何について言い争ってるのかよくわからない
GoやNode.jsが上手くいってる主因は非同期並行プログラミングのしやすさ
両者は方向性が真逆だけどそこが共通点で時代の要請
逆にC++が振るわないのは非同期並行プログラミングのしにくさ
その状況でRustが登場して非同期並行プログラミングのしやすい環境も装備されたという流れ
>>49
タスクはプリエンプティブにはできないよ
スレッド使えって言ってるの? Node.jsもプリエンプティブではないけど困っていない
タスクがプリエンプティブではないことを欠点だと主張する人は
欠点だという具体的な例を挙げてから主張すべき
>>51
そうだよ
ここで言うタスクはtokioやasync-stdの用語のタスクのことね
spawn_blockingでタスク生成すれば専用スレッドが割り当てられるので特定のタスク選んでプリエンプティブにできる (OSにタスクスイッチの制御を委譲できる) >>53
spawn_blockingみたいなAPIが用意されてるのはプリエンプティブなタスクの需要はあるんじゃないの
そこを否定する意味が分からない >>54
それはレイヤーが違う
まずOSスレッドは何をしようが常にプリエンプティブ
だからOSスレッド上で動いているタスクも途中で一時中断されたり再開されたりしうる
だからといってタスクをプリエンプティブだと言わないのはタスクの階層で話をしているため
タスクスケジューラに制御を戻さない限り他のタスクに切り替わらないため「プリエンプティブではない」と言われる
次にspawn_blockingで起動されるのもタスクの一つ
だからタスクスケジューラが管理するスレッドの中で動く
それがspawnだと一つのスレッドに対するキューに複数のタスクが割り当てられる
一方でspawn_blockingは一つのスレッドに対するキューにそのタスクのみが割り当てられる
それだけの違いであり両者ともにタスクスケジューラの管理下にあるタスクである
もちろん動作中も終了後もタスクとして同じ扱い
つまりspawn_blockingはプリエンプティブにするものではない
同じタスクでありスタックレスなコルーチンであることも同じ
>>55
その意見は成立していない >>56
確かにプリエンプティブという用語を使ったのは適切ではなかったかもね
タスクがスレッドを占有するか他タスクと共有するか選択できると言い換えればよいかな >>54
最初からspawn_blockingで呼ぶべきだと誰もがわかるような処理だけじゃないよ
Goと同じでRustもそのうちプリエンプティブなスケジューラが作れるような機構を用意すると思うけどね >>58
preemptiveは必要ない
シングルスレッドかつcooperativeなJavaScriptがNode.jsを含めて問題なく動作し成功している Rustってデータ競合を許さない、ってあたりが並列処理とめちゃくちゃ相性良いように見えるけど、
まだそういうスケジューラとか非同期ランタイムらへんの仕組みがちっとも枯れてないんだね
将来のデファクトがどうなりそうか、ってのはある程度見えてきてるのかな?
>>61
それはすぐに廃止された
そして現在tokioもasync-stdもプリエンプティブを許すコードは存在しない >>62
知ってるよ
問題認識の話をしてるんじゃん Node.jsはタスク単位で高い信頼性が求められるシステムでは使われない
イベントループがブロックしたら他のタスクを道連れにしてプロセス丸ごと再起動する以外に対処法がないから
それもexecution managerできちんとモニタリングしてればの話
JSやNodeとRustとはポジショニングが違う
>>64
イベントループがブロックすることはない
何を言いたいのか意味不明 >>64
Node.jsまで否定し始めるとは発狂もほどほどに >>58
rustでプリエンプティブなタスクって実装できるのかね
goみたいなシグナルでスイッチする仕組みは使えない気がするが 昔は標準で出来たのに「そういうのはライブラリでやればいい」って嘯きながら削除して、そのあと一生それが出来る標準ライブラリが登場しないいつものRust
>>67
Cで実装できることはRustでも実装できる
もちろんRustにもプリエンプティブなスケジューラは存在する
Rustで書かれたプリエンプティブなリアルタイムOSもある
>>68
Rust標準にプリエンプティブなタスクであるグリーンスレッドがあったのは
Rust 1.0が正式リリース(2015年)となる以前Rust 〜0.9 の試行している時代
しかし重厚となりベアメタルもターゲットとするRustでは不適なため放棄
例えばGoの方法だと巨大なランタイムや個別スタックが必要など
そのためRust標準ではスタックレスで軽いタスクを提供
さらに加えてasync/awaitもサポートし現在の軽く便利な環境となった 別に今でもasync-stdを使えばええんちゃうか?
>>69
ユーザーランドでプリエンプティブなタスク実現するという話なんだけど
具体的にどのライブラリがサポートしてるの? >>71
async_stdでのプリエンプティブな試みは軽さの方針等に合わず、組み込まれないままで終わった
>>72
上記の後継がasync_stdから独立していてsmolscaleとなっている >>72
lunaticってのがWASM限定だけどプリエンプティブ実現してるらしいよ
WASM以外はコンパイラのサポートがないと無理
>>73
async-stdがやろうとしてたのはプリエンプティブではないよ 話題になってる分野だとC++が惨敗すぎて
Rustの話題一色になってしまってる感じ
C++が落ち目なのはまっとうなエンジニアの間では共通認識だろ
変な拡張を使わなければ良いだけでは? 使いこなせないのを使えなとは言わない。
RustがGo位の位置にたどり着くのは、あと何年かかるかね
GoはWebとかのアプリケーションでカジュアルに使われるようになってきたから、使う人数もかなり多くなってきたけど、
Rustはそういうポジションにつくことないだろうから、現在のGoほどの人気になることはないんじゃない?
RustはC/C++のシェアを塗り替えていく程度だろうけど、そういう低レイヤーでは最強言語になりそう
RustがTIOBE Indexに出てくるのはいつなんだろう?w
言語機能としてはC++が完敗だから
過去遺産しか誇るものがない
シェアもユーザー数も過去遺産と言われてしまえばそうだが
そんなことは興味がないのでC++での非同期並行プログラミングについても語って欲しい
C++の非同期っていうとstd::asyncとか?
>>81
今26位で、Kotlin, Lua, Scalaとかより上なんだが KotlinやScalaは結局流行らずJavaで十分だし
Luaも一時期熱狂したけど記法や環境が多くの人の好みに合わずPerlのように嫌われてる
RustもC/C++で十分という認識が強くて普及せずに一部の通好みに終わる可能性がある
Rustは有力企業もプッシュしてるけど三つの言語の流行らない特徴を全て備えてる
そうこうしてるうちにRustより優れた言語がぽっとでて席巻する未来だってある
流行るの閾値高くない?
何位以上になったら満足なんだ
しかしTop10のVisualBasicやアセンブリが流行ってるとか言われてもあまり納得感はないな…
TIOBEってトレンドを計測してるわけじゃなくて、あくまで検索エンジンで検索結果のヒット数が多かったランキングだからな
CとかVBみたいに昔から一定の人気を保ち続けてるような言語がランキング高くなりやすいんじゃないかな
せやな
TIOBEはJavaScriptとアセンブラが隣の順位に並んでるとかおかしすぎるやろ
>>88
Scalaも当時は熱狂的なファンがいたよなw ScalaはJVMベースだという点以外は特に悪いところは無いと思うんだが
>>93
githubはアマチュアプログラマも沢山混じってる。
日経の調査ではプロのプログラマで最も使われている言語はC/C++だとされている。
なお、githubでも、CとC++を合算すると、9.82%、Rustは 0.694%で、
14.1倍の差がある。 >>98
C vs C++でもあるんだから足したらだめでしょ >>91
VisualBasicは結構使われているのではなかろうか。Excelなどで。
アセンブリは、基礎的なライブラリを作る人や組み込み、OS、BIOS
を作ったり、グラフィックや数値計算の高速化を行う場合に必要な場合がある。 >>99
Cにクラスを入れたものとしてC++を使っている人は多いはず。
MFCなどもそう。 >>101
いやいや、スレタイ通りこのスレではCとC++は対立する物として区別すべき 今どき言語マウントするやつは
メンタルも技術力もアマチュア
C++はCを基礎にしてるくせに、Cに歯向かって宿主を殺してしまう寄生虫みたいな
ことになってるからな。
いまのc++の拡張がな
autoとラムダとdecltypeくらいでやめときゃいいのにあとでボツになりそうな仕様までモリモリに盛りやがって下手したらobjective-cみたいになりそう
なのにいまだにpropertyも実装されてないとか
>>105
それほどへんなもの追加されてるか?
右辺値参照、constexpr、可変引数テンプレートは必要だしな C++11移行では、変数定義で、
TYPE a = b;
の形式が非推奨で、
TYPE a{b};
が推奨になった。
これは、C/C++の今までの伝統を全否定している。
C++11以後は、宿主を殺すウイルス的な存在に成り下がった一例。
>>110 みたいな爺さんは書き方変わるだけでアタフタw >>110
TYPE a{b};
↑これって何がうれしいの?
c++よく知らんので教えてほしい >>113
オブジェクトの定義に対して初期化子を与えると、オブジェクトの初期値を
決定することになるが、初期化子には次の4種類ある :
T a{b};
T a={b};
T a = v;
T a(v);
・このうち、あらゆる局面で利用できるのは、最初の T a{b}の形式のみ
(なおこの形式はC++11で新しく導入された。)。
・一番大きな理由はこの形式は「縮小変換を許さないから」とされる。
ただし、ややこしいのが、Tの部分を autoにした場合は、T a{b}の形式は
落とし穴がされるので使うべきではないとされている。
なぜなら:
auto z1{99]; // z1は initializer_list<int>型になってしまう。
auto z2 = 99; // z2は、int型。
ところが、Tが具体的な型の場合には、T a{b} が推奨される:
int x1{99}; // 推奨される書き方。
int x1 = 99; // 縮小変換があるので推奨されない書き方。
全く一貫性が無く、C++11が駄目な部分の一つ。 >>115
[誤字訂正版]
オブジェクトの定義に対して初期化子を与えると、オブジェクトの初期値を
決定することになるが、初期化子には次の4種類ある :
T a{b};
T a={b};
T a = b;
T a(b);
・このうち、あらゆる局面で利用できるのは、最初の T a{b}の形式のみ
(なおこの形式はC++11で新しく導入された。)。
・一番大きな理由はこの形式は「縮小変換を許さないから」とされる。
ただし、ややこしいのが、Tの部分を autoにした場合は、T a{b}の形式は
落とし穴が有るので使うべきではないとされている。
なぜなら:
auto z1{99]; // z1は initializer_list<int>型になってしまう。
auto z2 = 99; // z2は、int型。
ところが、Tが具体的な型の場合には、T a{b} が推奨される:
int x1{99}; // 推奨される書き方。
int x1 = 99; // 縮小変換があるので推奨されない書き方。
全く一貫性が無く、C++11が駄目な部分の一つ。 Rustはもっと最悪に汚い。
C++の最大の欠点は、仕様が難しいことに有るが、
Rustはさらに仕様が難しい。
よって、RustはC++をさらに悪くしたと言えて、改良には全くなってない。
c++は(ランタイム速度落とさなくても)できらぁ!ってなったらとりあえず入れるからな。
ある意味とてもガキくさいがそれはそれでありなポジションに到達してる気はする。
そんな凄いんだったらもっと普及してるよねRust
でも現実はブビにもコボルにも負けてる泡沫言語
単純に新しい言語だから累積となるユーザ数でまだ不利なだけ
2019年11月のasync導入で非同期プログラミングがまともに使えるようになってまだ2年余り
Linux OSのようにC++を頑なに拒否していたプロジェクトでもRustは受け入れられたように
C++に未来はないがRustには未来がある
最後間違い
C++に未来はないがRustも未来はない
日本は先進国の技術トレンドから5年以上遅れてるからね
C++erはレガシー脳が多いから
いい意味でのレガシーね
オリンピックレガシーみたいなw
C++はあんなみすぼらしいラムダ式用意して哀れやわ
貧乏の家の子が自家製ボタモチもって突っ立ってるようやわ
Rustやってる奴は現状アーリーアダプターで普及するにしてもまだ年月掛かると思う
んでその間にまた新しい言語が開発されみんなそっちに移って行くと
新しい言語はどんな問題解決してくれるんだろうな
動的型付けが復権するんだろうか
>>131
それならそれで無駄にはならない気がするが
考え方は継承されるだろうし SNS見てる限り、若い人でも人気は Rust より C/C++ の圧勝。
>>133
RustはVisual studioでデフォルトで選択できるようになったら普及するだろうな 北京五輪と東京五輪の開会式をプログラミングで例えるとどうなるやろ?
そのまま普通に
東京五輪 Rust
北京五輪 C++
ちょっとセンシティブな話だったか
与太話と思ってスルーしてくれ
すまんかった
>>139
Rustってそんな酷い言語だったんだ
手出さなくて良かったわ〜 RustはC,C++を駆逐すると思う。アレに拘泥する理由はない。
HighKingの至高の頂に座居するC++に勝てると本気で思っているのかね
>>144
過去資産があるから駆逐まではいかないかな。
でももっと利用されるだろう。
けど非同期のやつとかの分断をどうにかして欲しい。 ジワジワと侵食して気が付いたらいつの間にか利用していたって広がり方するんだろうな
>>116
これ見てクソ言語だなって思わないヤツいるのかね。 >>116
なんでこんな言語が使われるようになったんや? >>149
使われるようになったんじゃなく、既に使われてた言語を過去との互換性を崩さずに 変更しようとして/変更して そうなったんだよ。
その変化は今なお止まってないんよ。 >>149
C++が最初に使われ始めたころは、T a{b}のような記法はなく、
C++11で登場した。
使われ始めたころのC++はCの後継として丁度良いと思われるようなもので
あって、>>116のような変な仕様は入ってなかった。
最初は良かったが、後を突いていくと時々「え?」と思うような仕様が入り込み、
C++11で如実になった。
・templateの仕様も「え?」と思うことが多いものだった。
Stroustrap氏によれば、高速化に重点を置いて導入されたものらしいから、
分かり易さは犠牲になっているようだが、それにしても分かりにくいことが多い。
・C++にはライブラリが無かったので、C++11で導入されたが、それが
賛否の分かれるもので、恐らく6割くらいの人には質が悪く感じるものであった。 www.mercari.com/jp/search/?keyword=hr400p
こういう安い中古チューナ買って、Coinyをスカパープレミアム放送のICカード化して、
スカパープレミアムのチャンネル全部見れるし、USB HDDに録画フリー。
【avoCADO】 Coiny card Part4【仮想通貨】
http://2chb.net/r/avi/1640762750/ C++は必要な機能だけ使ってれば問題ないことが多いが、
コンパイルエラーメッセージがやばすぎる
まともな言語とは言えない
>>154
逆にRustのコンパイラのエラーメッセージは手厚く至れり尽くせりで感度もの >>154
C++は、学者がtemplateメタプログラミング関連などの理論的な正しさを
見せびらかしているだけの様な気がするよ。
「ほら、これでメタプログラミングができるだろ、俺の理論の正しさがわかったか」
みたいに。 ただ、だからといってRustがその代わりになるということではない。
RustはRustでC++以上に問題を入れ込んでしまった。
これもまた机上の空論の様な言語。
アセンブラとC言語
使わないけどFORTRANとCOBOLもそうかな
>>161
Ada は(少なくとも出た当時は)けっこう机上の空論ぽい機能てんこ盛りだった Cは貧弱すぎだろう。いまさらmallocとか書く気もおきん。
前にこれをC++スレかどっかで発言したら結構叩かれたけど
C++って結局はテンプレートが言語の真ん中にあるよな
他の言語色々やった上であらためてC++見ると俺にはそう見える
一応マルチパラダイム言語だからC++しかやったことない人は
テンプレートだけをフォーカスされるのは不服っぽいけど
Cではちょっとしんどいです
いろんなコンテナ使いたいです
そんとき型をパラメータ化したいです
ハゲ「テンプレートでみんな幸せ」
C++er「やったぜ」
C++規格の関係者「いろいろ仕様につっこんだぜ!」
C++er「あっはい」
>>166
概ね同意
テンプレートは便利だけど使いすぎてワケワカメってなりがち Rustでバブルソート書いてみたがすげー書きやすいな
食わず嫌いだったかもしれん
コンパイルエラーがめっちゃわかりやすい
rustのエラー報告は全てのプログラミング言語で最高の親切さだと思う
他の言語がサボりすぎなんだよな
rust書くと他の言語かけなくなる
そんなバブルソートバカにせんでもよかろうに
大学一年で最初の方に習うし、初めての言語触るにはまあまあ良い題材では
少しいじってcombソートにしたらクイックソートにもひけをとらないしな。
Rustで双方向リストをマージソートでソートするとかだとめんどくさいことになる気がする
バブルソートがすげー書きやすいってどのへんが?
逆にそんなもん書きにくい言語なんてあるの?
fn main() {
let mut v = vec![8, 4, 3, 7, 6, 5, 2, 1];
let bsort = |v: &mut Vec<i32>| for i in 0..v.len() {
for j in 1..v.len() - i {
if v[j] < v[j - 1] {
v.swap(j, j - 1)
}
}
};
bsort(&mut v);
println!("{:?}", &v);
}
↑書いてみた
細かいところは日本語版wikipediaに準拠
ソートの話はどうでもよくて要点はRustに対してのこの部分だと受け取ったが
>>170
> 食わず嫌いだったかもしれん
> コンパイルエラーがめっちゃわかりやすい バブルソートは理解が難しいわりに現実に使われんのがな。
それだったらクイックソートをだな。
>>182
> バブルソートは理解が難しい
えっ? >>183
頭の良さは人それぞれなんだから馬鹿にしない ダブルアレイは原理が簡単にもかかわらず、十分バグが取れるまでずいぶん時間がかかった。
>>180
Rustはコンパイラが出すエラーメッセージが詳しすぎて解決案まで示唆してくれたり親切すぎる
他のコンパイラ言語だけでなくインタプリタ言語まで広げても一番親切なプログラミング言語システムだと断言できる まあC++にテンプレートないならそこまで使わんわな
Stroustrup氏の脳内では、テンプレートの目標が高速化であるということなのが
問題の始まりの気がする。
マクロ=高速化用途で使われているもの
という見方が如何にも実用プログラムを書いたことの少ない学者だと思う。
>>186
その代わりメモリーは使わないから貧乏な俺でも使える >>179
そういうことではなく
おそらく>>170が言いたいのはコンパイラが出すエラーがめっちゃ親切なことだろう
こっちで書き換わってるからここにmutを付けなさいとか
ここで所有権が移動したのに後で使用してるからここに&を付けなさいとか
これをuse宣言するのを忘れてますよとか
この変数は宣言されず使われていますがこの変数名のスペルミスではありませんかとか
といった簡単なものから
複雑な借用関係をちゃんと登場人物たちをはっきりさせてあっちとそっちがこれこれでマズいのでこうしてみたらどうかなど
こんなにきめ細かく親切なエラーを出すコンパイラ&インタプリタは他の言語と比べてもトップではないか >>195
そこは目から鱗だよな
ここまでできるなら、他の言語も頑張れよと言いたくなる 言語として所有権の概念がないからその辺りの指摘はしないけどVS2022のC#も結構色々提案してくれるぞ
このながれでこれを言う意味なんてないけど
わかるやつだけわかってくれたらいいんだけど
Rustのコンパイラ昔は酷かったよな
無慈悲なボローチェッカと戦ってたよな(´;ω;`)
>>200
コンパイラというよりもnon lexical lifetimeが入る前の言語仕様の制約が厳しくて辛かったんじゃないかな
>>201
コンパイラのバージョンがsemverにしたがってるうちはメジャーバージョンアップしないんじゃないかな
基本的に過去との互換性は崩さないし、必要ならエディションで非互換な変更もできるようにしているので、
メジャーバージョンアップしてまで互換性崩したい理由がなさそう どこかでPython 2 -> 3みたいなことが起こるかもよ
>>203
Rustは後発言語なだけあって
今どきのプログラミング言語の成功部分を洗練して採り入れてる
だから互換性のないバージョンアップをする時はRustより新しい言語が新たに成功してそれをRustも採り入れたくなったが互換性を維持したままでは出来ない時が来てから >>202
そのnon lexical lifetimeが入る前の言語仕様の制約が厳しい件なのかどうか教えて
このリンクリストの実装でpush_back()のコードがlifetimeでコンパイルエラーとなる話
https://qnighy.hat
enablog.com/entry/2017/05/06/070000
今このコードをコンパイルすると問題なく通って実行もできてしまう
Rustのコンパイラはどんどん賢くなって制約が無くなっていってるんだな >>195
エラーメッセージの親切さで言うとVC#がトップだと思ってるけどそれ以上?
C++でハマったときの沼の深さは異常だからそんな親切なら乗り換えたくなってきたな >>207
push_backの例はまさにNLLでコンパイル通るようになるコードだね C++のTMPのエラーメッセージとRustのジェネリックのエラーメッセージ
C++のはもはや意味不明だがRustのはまだ人間が読める
あまりに親切すぎるメッセージなので、それならそういう風に変更したものをコンパイルしてみて、「こう変更したらコンパイルできました」となればいいなぁ
とRebuildの宮川さんが言ってました
cargo check --fix である程度は勝手に修正してくれるんだっけ
>>209
C#も親切だけど、Rustはそれ以上だよ
これらに比べると、C++のは情報が無いも同然 C++でハマるのはむしろコンパイル通ったあとだからw
みんなそれはご存知だとは思うけどw
Rustはコンパイルが通ればメモリ問題や競合問題が起きず、プログラム自体に専念できるのがいいよな
そしてコンパイラが出すエラーが親切に手取り足取りしてくれて、すぐ修整できてコンパイルも通しやすい
>>218
つくづく考えた奴は天才だとおもうわ
逆になんでいままででてこなかったんだろうとも思う
Linuxつくるのもいはいけどそれをつくる道具を作るのが先でもよかったような
linuxを全部rustで書き直したrust-linuxみたいなのを作る奴もそのうち出てきそう >>219
書き直したとして、1日でビルドできたらいいね Rustの考え方の基になったCycloneが目指してたのがまさにそれだね
>>219
> Linuxつくるのもいはいけどそれをつくる道具を作るのが先でもよかったような
GNUって言うかストールマンはその考えでしょ
> linuxを全部rustで書き直したrust-linuxみたいなのを作る奴もそのうち出てきそう
言い出しっぺの法則ヨロ >>222
いや、マジで俺がやってもいいぞ
誰もやってなかったら俺が次のLinusになれるってことか
むしろお前らは絶対に真似しないでほしい rustのコンパイルが遅いのは依存ライブラリやジェネリスクの実体化によりコード量が多くなっているからで
コンパイラ自体は並列化とか頑張ってて高速という話を聞くけど実際のところCやC++と比較してどうなんだろうね
ヘッダファイル周りの枷がある分CやC++が優位とも簡単には言えない気がする
>>223
真似はしないから一つだけ聞いてみたい
どこから書き直し始める? コンパイラの並列化で
数十コアも効率良く使えるなら
実質的にコンパイル時間は無視できる
>>228
まあそれは冗談でも「rust os 自作」でググるといろいろでてくるからそれを参考にやってみるわ
rustでOS作ってる先達者が結構いるみたいだからそれを参考にLinuxカーネルの移植をがんばってみるわ >>227>>229
まあそんなんだろうと思ってたけど、せめてリーナスがなぜLinuxを作ろうと思ったか、どんな哲学で設計したかぐらいは読んでみると良いと思う
タダで読める情報はいくらでもある >>230
「それがぼくには楽しかったから 全世界を巻き込んだリナックス革命の真実」は読んだけどそれじゃだめかな? 現時点で2200万行もあるから、完全に移植しようとしたら毎日1万行のコードを移植し続けたとしても、6年はかかるね
そんな爆速で順調に行くわけないし、よっぽどの天才でもなければ1人では生涯に終えるのは無理かな
省ける部分を省くとしたら、何万行になるのかな?
>>224
C/C++に比べたら速いよ
でも、C#に比べたらC/C++と同列に遅い、という程度 rust触ったことないからわからないけどC/C++よりコンパイル速いわけないじゃん
>>235
それ4〜5年前の古い情報
URLにprevとありそのトップページに2018年12月6日とあるように昔のページを残してある フルビルドと差分ビルドで区別して議論しないと比較難しいね
あと差分ビルドについてもバイナリ生成までするのかソースのチェックで十分なのかでまた変わってきそう
流行る言語は登場から10年くらいでウワーっと大流行するんだが、Rustにはそんな気配はないから
精々Goとかと同じような感じにしかならんやろなー。
>>240
新規案件がC++ではなくRustになっていきつつあるように
じわじわと着実に置き換わっていくのだろう
一方的にC/C++が喰われていくのが止まる理由も見つからん >>242
goレベルでも十分流行ってると言えると思うんだけど >>240
VisualStudioの新規プロジェクトの作成でデフォルトで選べるようになれば普及するだろうね >>246
C++もVC++が出てから一気にCを喰い始めたしな
なんだかんだWindowsの影響力はめちゃくちゃ大きい 当時と今とじゃデスクトップアプリの置かれてる状況が全然違うと思うけど
何をもって普及とするかといえば、まだにVB書いてるやつもおるし、組み込みではRustなんて考えられないし、フロントエンドは
JS/TS/Nodeでほぼ不動。そうなるとJava/C#、Railsなどのビジネス系エンタープライズだが、メニーコア用のGoとかのほうが
敷居が低い分だけ人を確保しやすい。言語的な優劣では普及は進まない
当然、高スループットが求められる大企業のエリートでは使われるだろうけど、日本の中小企業で使われるとか想像ができない。
奇々怪々C++は食われていくだろうけど、マイクロコントローラなどでCが食われるなんて無い。データ分析はPythonとかJuliaとか
ビックデータはHadoop・Spark(JavaやPython)だろう
だが当然ながら*nix系は一歩先を進んでるRustだが、ちんまいコマンドラインのプログラムとか、デバイスドライバだとかそういう
分野でしか使えない(使われない)と思う。あとは自動運転なんかのプログラムならRustが使われてたりするが、そういう
技術者はPythonも使えるし、Juliaなんかもすぐ覚えられる。スマホアプリ系もRustなんてありえない
あと残るのはデスクトップアプリケーションとか、これも今はElectron系とかがあるのでネイティブで書く意味があまりない
普及なんてしなくていいんだよそもそも
それを必要とするやつの手に届いたら十分なんだよ
C++でやってた分野の一部でもRustで書き換わって
それでメンテする連中がラクできることになって
一方でユーザ側にも恩恵はあるだろうしそういうのでいいんだよ
ド素人のアマチュアプログラマに届く必要はないんだよ
普及しなくていいし、してもらいたくない
なぜならうちの会社が業界でトップを維持してる秘密だから
他社のウエブサービスより圧倒的に早くセキュアなのはずばりRustをつかってるから。
その前はLispを使ってた。
だから真似してもらいたくない。
まあ、真似できないたまろうけどw
>>249
これrustに限らず、現状がそのまま続いて新たな言語で置き換わることはないだろうとしか言ってないよね >>251
そういうことやね
それを必要としてるやつはコッソリ一人で握り込んで
それを優位に役立てていくだけのことだから >>249
組み込みはrust向きなとこなんじゃないのかね。組み込み業界のことは一切知らんからアレだけど。 Rustが組込向きかどうかはともかく、LinusはC++に対してはCの問題を何一つ解決せず、事態を悪化させるだけと言っていて、Rustについてはドライバを書けるようにするところまでは実際にやってきているらしいよ
>>249
組み込み以外にミドルウェアらへんでも使われるようになると思う
OS、RDBMS、Webサーバとか
ミドルウェアよりも上位レイヤーのアプリケーションだけで見ると、GCがある言語でもだいたい十分そうだし、Rustは目立たなそう rustはc++よりbetter cしてるから徐々に市民権得るだろうな
>>251
> 他社のウエブサービスより圧倒的に早くセキュアなのはずばりRustをつかってるから。
おお、なるほど
> その前はLispを使ってた。
ズコーッw
作り話はもっとうまく作れ Rustってクロージャの再代入できない?
null許容することになるから出来ないようにしてる?
型が同じなら再代入可能だけどクロージャはそれぞれ別の型を持つので単純には代入どきない
Box<dyn Fn()>などに変換すればできる
Lispってセキュアなコード書くのPythonより難しくないか
こちらのまわりではスクリプト言語で書かれていた物の高速化でRustへ移行が多いな
レスポンスの意味での高速化もあればリソースとしてのCPUタイム激減もある
使用メモリも激減するためクラウドでもオンプレでも費用支出が激減し桁が変わる場合もある
>>255
さすがにc++03とかと比較されても…… よく知らんのだけど、カーネル書くのに抽象化って必要なの?
もしいらないんだとしたらC++がカーネル書くのになんのメリットもないと考える気持ちもわかる気がする
Rustの場合は安全性がついてくるので抽象化がなくても使う価値がある
Rustのオブジェクトシステムって実際C++のそれと比べたら遥かにわかりやすいよな
traitって概念ほんまありがてえわ
>>266
パッと思い浮かぶのはファイルシステムと仮想ボリュームぐらいだけど、C++がメリットになるとは思えんな >>264
DiscordがGoで作られてたバックエンドの一部をRustで書き直したらめちゃくちゃコスト下がったってニュースあったな
C++がRustに置き換わるってよりスクリプト言語やGC言語で作られたものが置き換わっていくのがまず先だろう どうでもいいけど、このスレ個人の思い込みと間違いだらけに見えるな
>>270
それは今でも粛々と置き換わってるだろう
Rustが使われるのは、スクリプトやGC言語ではパフォーマンスなどが得られない分野なんだろうと思う DiscordがRustに移行した当時のGoは大分ウンコだったけど、今ではわりとマシになっちゃったよ
なんでこうなっちゃったんだろうね。一部の馬鹿が日本をどんどんダメにしてる気がする。もっとちゃんと比較できるよう上手く使えばいいのに。
>>274
ああ、おれが言いたかったのはGCの停止時間がマシになったよ、ってことだけだよ
言語機能は大して変わってない
でもGenericsは今月中のリリースが予定されてる1.18に載るはず GCがある言語のパフォーマンスが悪いというのは思い込み
>>279
トータルのパフォーマンスが問題じゃないんだ、予期せず処理が詰まったり急に負荷があがったりするのが問題なんだ。
まぁ今時のGCはストップザワールドは起きないだろうけど。 >>280
GCが動いて困る場合は、現状でもC++かCなどで実装されているはず
なので、パフォーマンスを向上させる目的でGCあり言語をRustで置き換えるというのは、あまりないと思われる >>281
あるよ。いま、うちがやってる移植プロジェクトはその案件。
他社がそんな考えだから今の所引く手あまた。一社独占。大阪にもう1社あるってうわさだけど。。。
客が数十件待ってる状態。年収軽く3本いくわw まぁ、GCの弊害がわからず採用して実稼働に入って困ったような技術要素選定バグの場合は、言語置き換え対象としてRustが選ばれるケースはあると思う
>>283
GCの問題じゃなくてパフォーマンスの問題でリプレースなの?
元言語何? 年収3本って3000万ってことか?
内容から、フリーランスでRustへのリプレースを専門でやってる感じだが、個人特定されかねないぞw
>>283
レアだから現在のcobolみたいなもんか Rustに置き換える理由はパフォーマンスより保守性とか堅牢性だと思う
開発者が少ない現状だと単純に保守性向上のためだけに外注するようなケースは少なそうだけど
今のシステムが不安定で改修もままならないからRustで作り直すってケースなら結構ありそう
トヨタなんかの車載システムはCとRustで開発してるとか聞いたことあるが
>>281
今までGCありスクリプト言語をRustへ置き換えたり置き換えつつある
GCの有無は条件ではないのだけど速さ省メモリに安全性と書きやすさ等でRustとなった >>284
サービスの立ち上げ期にGC影響も見越してカリカリにチューニングするってのは早すぎる最適化なんじゃないのかね
rustで他の言語と同じくらいの早さでサービス作れる人材がそろってるなら良いが スクリプトからの置き換えとして、VMを配布したくない(JVM/.NETが除外)、それなりに言語機能が欲しい(Goが除外)となるとRustくらいしか残らんのだよな
逆にそれらを許容できるなら別にRustじゃなくていいんだが
Firefoxがいまだに勝てないのに速さとか言われてもな、省メモリならEdgeだし、自分たちがしたいだけでしょ
VMとかgoとかスレ違い
なんでC/C++/RustでGCとか出てきてんだよ
ム板ならGCの話をするならスレ立てて簡易実装くらい出して、有無の差異、モデルの差異、各言語の比較をしてほしい
前提の違う話を複数絡めて盛りすぎ
※明らかな嘘は論外
うちはNode.jsからの移行先がRustになった
JavaScriptよりプログラミングしやすくなった
C vs C++ vs RustなんてRust圧勝で勝負ついてるんだから話すことなくない?
>>299
言語機能としては圧勝なんだが、人やソフトなどの開発環境が惨敗だから困るんだよな >>302
今一人勝ちのJavaだってそうなるまでに20年かかったんだから今判断しても意味なくね? >>258
Lispとかいたらズコーってされたけど適材適所だと思うぞ
ルンバがLispで書かれているのは知ってるよね?
強力なメタプログラミング機能とインタラクティブな開発が必要なら採用してみてもいいのでは? >>304
セキュアなWebサービスはどうしたんだよw rustに置き換えようとして担当が逃げ出したプロジェクトがかなりあるわ。。これからその地獄がはじまる。
どうしたらLispでセキュアなwebサービス作れるん
Lispだろうと多言語だろうと新しめの通信とかSSLとかのライブラリを探すとこからスタートじゃない?
Javaは言語登場から10年くらいで多くの人が利用してたし開発環境も続々でとような。
>>306
置き換え元のコードが酷かったんじゃね。C++のコードとかだいたい酷いし。 現役プロダクトのコードを別言語に置き換えるのってrustに限らず大変なのでは
全面的な置き換えはプロダクト全体の再開発に等しい
特定の担当に押しつけるのではなくチーム全体で徐々に新規部分から置き換えた方が成功率高そう
>>314
> C++のコードとかだいたい酷いし。
×だいたい酷い
○すべてが酷い
◎すべてがゲロ以下に酷い 一般的にコードを『置き換える』という気構えだと失敗
少なくとも移植先の言語に合わせて何らかの内部設計のし直しからが最低限のスタート
目的が効率アップにあるなら並行や並列が設計として入ってくるだろうし
目的がGC無くしてメモリ省力化だけであってもデータ構造の見直しは必須など
ねえねえ
ベクタの特定のターゲットの添え字を返すfind(v, target)を作ったとして、
ターゲットが見つからなかった場合のエラー処理はどうするのが良いと思う?
C/C++だと返り値を整数にして-1だったら見つからなかった、と言う感じが多いと思うんだけど
Result<usize, &str>とかにしてエラー内容を表す文字列を返しちゃう?
>>318
まずRustではそういうのはベクタに対して実装せずにスライスに対して実装する
次にRustではそういったものにはResultではなくOptionを返す
最後にそのような機能は標準ライブラリを使えば色んな意味で間違いがない >>98
しかしC言語技術者は求人市場では圧倒的に不足していると言われてる
どこにいるんだか >>324
同記事の引用
『プログラムをRustで書き換えることで、サービスは10倍速くなり、レイテンシーも大幅に短縮された。サーバーの数を減らすことができたので、結果的にエネルギー消費量も減少した。
「エネルギー効率の高い言語はRustだけではなく、昔からあるC言語もエネルギー効率は高い。しかしRustは安全性を犠牲にすることなく、省エネ化を実現した初めてのメインストリームのプログラミング言語だ。CやC++で書かれたプログラムが抱える深刻なセキュリティ脆弱性の70%は、メモリー安全性の問題に起因している。それに対して、Rustは安全性の問題を抱えていると感じることなく、エネルギー効率を高められる」とMiller氏は言う。
しかし、Rustにも習得の難しさをはじめとする課題はある。
経験豊富なエンジニアでも、Rustを使いこなすまでには、この分野に詳しい専門家のサポートを受けながら、3〜6カ月の学習期間が必要だとMiller氏とLerche氏は言う。「Rustの習得を、野菜嫌いの克服に例えるエンジニアもいる。使いこなせるようになれば好きになる人が多いが、多くのエンジニアはそうなる前に見切りをつけたり、あきらめたりする。Rustは持続可能性とセキュリティに影響する可能性があるが、その力を発揮するためにはまず、ブロッコリーをブラウニーに変えなければならない』 コンピューターのエネルギー効率が高い代わりに人間の効率が下がるんですがそれは
コンパイル時にめっちゃエネルギー使ってる
Tier 1のプラットフォームの最新数バージョンくらいはバイナリ配布する仕組みがcargoに必要
>>326
まぁ作ったあとの稼働と運用考えたら総じてプラスになるでしょ。ならない? >>326
これよく言われるけど言語による生産性の差って定量的にデータ集められてるのかな メンテナンスフェーズに入ったとしても、人件費より電気代の方が高くなるようなことってなかなかなくね?
そんな大成功を納めたサービスってどれくらいあるんだろうな
>>329
そうそう。
昔はJavaでやろうとしても人材不足でリプレースできなかったけど今は余裕で集められるもんな