Rust part18

■ このスレッドは過去ログ倉庫に格納されています
2022/12/10(土) 18:17:02.61ID:XSNoXTPt
公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust

Web上の実行環境
https://play.rust-lang.org

※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/

※次スレは原則>>980が立てること

前スレ
Rust part17
https://mevius.5ch.net/test/read.cgi/tech/1665063793/
2023/01/06(金) 23:51:15.52ID:sXnz8uH8
>>762
>>759を動かそうとしてるんなら"calc\0"は第1引数じゃなくて第2引数よ
もうちょっと落ち着いて色々見直しなさいな
764デフォルトの名無しさん
垢版 |
2023/01/06(金) 23:53:05.97ID:/3LWOZ61
>>761
10.1に書いてるコードがすでに参照使って書いてるじゃん
PartialOrd足せばそのまま動くけど?
2023/01/07(土) 00:26:35.07ID:+QPNW5aO
>>763
MSDNを見る限り単にアプリを起動するだけなら第一引数でも第二引数(読み込み専用不可)でも大差なくない?
動くようになった状態で入れ替えても問題なく動作するし
2023/01/07(土) 01:02:32.01ID:dLMo+qnq
>>765
こっちじゃ第1引数使うなら"C:\\Windows\\system32\\calc.exe\0"以外は
GetLastError()が2(ERROR_PATH_NOT_FOUND)を返してきて動かんのだけど……
MSDNも第1引数の説明にだけパス検索はしないだの拡張子つけろだの書いてあって、その通りに動作してるだけのように見えるし

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw

> The function will not use the search path. This parameter must include the file name extension; no default extension is assumed.
2023/01/07(土) 01:04:28.02ID:piTlebRA
>>761
とりあえず修正したコード

fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut res: &T = &list[0];
for elem in list.iter() {
if *elem > *res {
res = elem;
}
}
res
}

forの変数elemの型が諸々の事情でTになってたから&Tに直した
ついでにTのCopyもいらなくなりそうだから外した

letとかも同じだけど
let &x = ...
みたいに受け取る側に&をつけるとxの型は入れる値の&を外した型になる(とても雑な説明)
2023/01/07(土) 01:08:28.51ID:4uiRCztN
iter().min::<T>()みたいにかけないっけ
うんこまん
2023/01/07(土) 01:32:02.10ID:kRb596bj
>>767
ありがとうー
そういう仕組みなのね。勉強します
2023/01/07(土) 01:44:37.82ID:BXkfdHSu
>>769
そのへんはパターンマッチと同じ理屈で解釈されるよ。
2023/01/07(土) 02:06:28.88ID:+QPNW5aO
・system()っぽい関数(起動したプロセスが終了するまでブロックする)
・CreateProcessW失敗時は起動失敗を呼び出し元に通知したい
・成功時に戻すべき情報はない
・Rust的にはResultを返すのが定石?
こういう時のコーディング例とかググっても全然出てこなくね・・・
重要なのはOk/Errのみで返り値は不要みたいなケース
とりあえずbool返しにしておくか

>>766
あれ?確かに。すまん気のせいだったっぽい
772デフォルトの名無しさん
垢版 |
2023/01/07(土) 02:31:58.39ID:6JfdJVIo
>>767
> if *elem > *res {
if elem > res でいいよね
773デフォルトの名無しさん
垢版 |
2023/01/07(土) 02:40:46.97ID:nUzzs5ki
古い劣化日本語訳を読んじゃってるみたいね
最低限本物のThe Bookを参照してから質問しよう
https://doc.rust-lang.org/book/ch10-01-syntax.html
2023/01/07(土) 11:49:37.35ID:TSp0PKQI
>>747
変数間でのオブジェクトの共有が気になるシチュエーションはjavaなんかは結構あると思う。
2023/01/07(土) 16:25:18.46ID:dLMo+qnq
rust-analyzerにもVSみたいにドロップダウンでplatform切り替える機能ほしいのう
cfgで複数のplatformに対応しているタイプのライブラリで便利そう
2023/01/07(土) 16:40:32.23ID:+QPNW5aO
継続不可能な状態→エラーダイアログを表示
ここまではいいけどこの後の後始末ってどう書くのがいいんだろうな
後始末のために共有データ(起動時に設定ファイルから読み込む)にアクセスしたいが
Dropトレイトにしろパニックハンドラにしろmainとは別スコープなのでアクセスできない
後始末のスコープ中で共有データを読み直すという手もあるけど、本当に意図しない状態で
強制終了する場合にファイルのロード&パースをするのが望ましいとは思えない
Dropトレイトの初期化時に共有データの参照を渡しておくとか?
2023/01/07(土) 17:10:37.53ID:piTlebRA
>>776
mainの中で初期化してResultを返す本処理を呼ぶ形は無理?

fn main() {
// 初期化(設定読み込み)
let info = ...;

// 本処理
let result = main_body(&info);
match result {
OK(_) => {}
Err(e) => {
// エラー処理(info使える)
}
}
}
2023/01/07(土) 18:02:32.48ID:+QPNW5aO
>>777
それコードの位置が逆なだけじゃ。というかResult返しの実装方法を理解できていない
とりあえず共有データを保持している構造体にdropを実装してみた
自身へのアクセスは可能だしmainの終了時に実行される・・・はず
779デフォルトの名無しさん
垢版 |
2023/01/07(土) 18:21:41.85ID:S1LntPIN
>>777
よくこの文章を解釈できたな
素直にすごいわ
2023/01/08(日) 00:10:22.65ID:lAEXMGQ2
Rustってゲームに向いてそうなイメージあるけどどうなんだろ
メモリリークは相当起きにくいよな?
2023/01/08(日) 00:39:44.59ID:li8iVC1C
ゲーム開発はトリッキーな手品も使うだろうから向いてないんじゃないか
2023/01/08(日) 00:51:12.10ID:RrQeMuL+
今のご時世に非標準的な実装をするゲームとかOSのバージョンアップで爆死する未来が見える
2023/01/08(日) 01:11:48.94ID:WtSMxRkj
>>782
OSに関係無いところでのトリッキーなテクニックは有りえる。
例えば、複数のポインタ用のバッファをまとめてnewで確保してから、
直後に値を代入するようなことはC/C++では簡単に行なえる。
ところが安全性重視の言語だと、非初期化状態のポインタは許されないから、
少なくともnew演算子が自力でNULL初期化しなくてはならないので、
無駄になる。
他にも、配列の範囲チェックが無駄になる。
2023/01/08(日) 01:15:49.98ID:WtSMxRkj
>>783
ちなみに、
「非初期化状態の変数」は不安定になり易いので減らした方が良いとされているが、
BYTE *dst = new BYTE[1024]; // dst[k] はこの時点では未初期化状態
memcpy( dst, src, size );
のような時にはC++では効率を考えると仕方が無いものと考えられている。
0初期化すると無駄になるから。
785デフォルトの名無しさん
垢版 |
2023/01/08(日) 01:45:10.78ID:f5aNmtma
ヒープでいいならVec::with_capacityしてデータ入れた後にBoxed sliceにすればいい話だね
スタックでゼロ初期化した方が性能はいいと思うけど
2023/01/08(日) 02:04:33.63ID:DAo3J3pj
Box<dyn T>はBox<dyn T + 'static>のライフタイム省略版って聞いてたのに片方だけエラーになる
なんじゃこりゃ

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=21ad8deab1cb8fb311aeed2ee668bf71
2023/01/08(日) 02:36:10.85ID:x4fu54u1
Rustのメモリ安全性にはメモリリークしないことは含まれていないんだよね。
Rc<T>で循環参照するデータを作ってもコンパイルエラーにはならずメモリが解放されないままだったはず。
まぁメモリリークしててもメモリがある限り正しい結果を返すわけだし、メモリがなくなったらクラッシュするので間違いが起きたまま動作しつづけることはないけど。
788デフォルトの名無しさん
垢版 |
2023/01/08(日) 02:55:51.04ID:fOddL1iF
Rustは例えばGodotではGDScriptが実質Rustだし相当ゲーム制作に向いてる
https://gitlab.com/the-SSD/gdscript-compiler
789デフォルトの名無しさん
垢版 |
2023/01/08(日) 04:35:49.54ID:kuKYL1oy
>>786
なんじゃそりゃ
どこでそんなデタラメ仕入れてきたの?
790デフォルトの名無しさん
垢版 |
2023/01/08(日) 06:55:53.23ID:FeGYfhwG
技術評論社の書籍だろ。
2023/01/08(日) 11:05:23.60ID:DAo3J3pj
>>789
The Rust Referenceだった
この本デタラメなん?
https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
792デフォルトの名無しさん
垢版 |
2023/01/08(日) 11:05:27.68ID:wpyfySyl
>>781
そういう部分だけunsafe使えばいい。
unsafeダメ原理主義者になるな。
2023/01/08(日) 11:21:27.20ID:D257opQI
>>791
そこにはライフタイム省略版とは書いてないよ
expressionなどからライフタイムを推論できない場合はstaticになると書いてある
(例えばコード例のようなタイプエイリアスの場合など)
playgroundのコードではu2のライフタイムから推論されるからstaticにはならない
794デフォルトの名無しさん
垢版 |
2023/01/08(日) 11:35:19.20ID:4wy9Fp4t
>>791
これでしょ?

If the trait object is used as a type argument of a generic type then the containing type is first used to try to infer a bound.

If there is a unique bound from the containing type then that is the default
2023/01/08(日) 11:50:51.08ID:DAo3J3pj
>>793
は〜んなるほどな
関数引数とか構造体メンバとかの'staticに推論される場所で使うことが多かったから勘違いしてたっぽい
ありがとう
2023/01/08(日) 12:37:06.99ID:RrQeMuL+
みんな大好きUnityなどと比べたらRust由来の効率低下なんて微々たるもの
797デフォルトの名無しさん
垢版 |
2023/01/08(日) 13:59:02.14ID:UBD4N3HA
https://cdn.discordapp.com/attachments/953965039105232906/1061347007664500737/knhtsxphnnaa1.jpg
798デフォルトの名無しさん
垢版 |
2023/01/08(日) 14:01:25.73ID:tWJ5hYnn
https://lr.mint.lgbt/img/knhtsxphnnaa1.jpg
2023/01/08(日) 14:08:03.69ID:OlteebrS
>>796
それは言語としての魅力があればの話。
2023/01/08(日) 15:57:06.75ID:LmL7tvTF
>>797
安心安全だなあ
2023/01/08(日) 16:08:08.46ID:vMQQXEk1
>>797
unsafeの絵面ヤバくて草
2023/01/08(日) 16:09:10.68ID:VztT2gmz
unsafeで書いたほうがコンパイル速度速くて好き
2023/01/08(日) 16:30:50.12ID:9eCFH/Xi
せめてunsafeの間くらいは起こしてやれよ
2023/01/08(日) 19:26:34.22ID:2yRrU7ur
Rustで多量のファイルを高速に読み込みたい場合ってどうすればいいの?
std::fs::readはVec<u8>を返す=メモリアロケータが動く=遅い
十分なサイズのVecを事前に確保してreadなりReadFileなりを叩けば
任意のアドレスに読み込んでくれるけどほかに方法はないのかな
2023/01/08(日) 20:32:01.24ID:9eCFH/Xi
Rustに限らずreadで遅いと感じるレベルならOS依存のmmap(memmap)くらいしか思いつかない
速さ目的で使ったことないから本当に速くなるか分からないけど
2023/01/08(日) 21:00:35.09ID:gNhHKSa0
The Book を進めていくと Box<trait> でエラーになって Box<dyn trait> に変えろって言われるんだけど、dyn ってなんですか?
2023/01/08(日) 21:02:45.41ID:lAEXMGQ2
動的 ダイナミック
実行時に決まる的な
2023/01/08(日) 21:06:58.13ID:gNhHKSa0
>>807
なるほど
trait は動的なのでより明確になるように dyn キーワードが追加された... という理解でいいでしょうか?
2023/01/08(日) 21:11:02.19ID:rBa/PYaz
>>805
1MB/1000個くらいのファイルをstd::fs::readで読みながらVec[u8]に
extend_from_sliceで追加していくコードを書いてみたら数秒かかった
さすがに遅すぎ
せめてVec<u8>→Vec<u8>(の任意のインデックス)みたいなmemcpy的な
コピー手段はないのなか。どのくらい早くなるかわからんが
2023/01/08(日) 21:31:03.29ID:LKKCPrwt
>>809
>1MB/1000個くらいのファイル
これはどういう意味?
/ は、割る、または、OR(または) の意味で用いる。
もしかして、
一個当り 1MB のファイルが 1000 個、合計サイズ 1GB の
ファイルのことを言っている?
2023/01/08(日) 21:32:08.52ID:LKKCPrwt
>>810
ちなみに、そのくらい巨大になると、Rustの「安全機構」は体感速度に
まで影響する。
2023/01/08(日) 21:37:22.02ID:Ot3XQ+MC
>>810
わかりにくくてすまん。ファイル総数1000程度、合計サイズ1MB程度
2023/01/08(日) 21:51:35.12ID:iCNAe1YS
>>809
リリースビルドでその速度?
2023/01/08(日) 21:52:13.93ID:lAEXMGQ2
>>808
間違えてるかもしれんが俺の理解だと
>>traitは動的
traitは静的だけど、trait実装してる型が静的/動的に決まるかで
動的→dyn Trait 静的→ジェネリクスやimpl Trait を使い分ける
よくある例では
Vec<T>はT1つ確定して他の型は一切受け付けないけど
Vec<Box<dyn Trait>>はTraitを実装してる型なら何でも入る
2023/01/08(日) 22:01:47.30ID:gNhHKSa0
>>814
分かりやすい説明でなんとなく理解できた気がする
ありがとう
816デフォルトの名無しさん
垢版 |
2023/01/08(日) 22:13:49.41ID:V1l2P4XZ
>>806
いい加減に本物のThe Book読めよ
ちゃんと説明されてるだろ?
https://doc.rust-lang.org/book/ch17-02-trait-objects.html
817デフォルトの名無しさん
垢版 |
2023/01/08(日) 22:45:09.72ID:HTBsXmSw
>>809
extend_from_sliceだと遅そうだね
io::copyにしてみれば?

ちなみにその1000個をcpしたらどの程度で終わる環境?
2023/01/08(日) 22:48:55.19ID:9eCFH/Xi
>>809
memcpyと同じことしたいならstd::ptrにcopyとかcopy_nonoverlappingが用意されてる
ただ引数はポインタだからunsafe

copy_nonoverlappingのExamplesがやりたいことに近いと思う
この例はコピー元のVecを空にしてるけどu8みたいなCopy型に限定すればコピー元のVecをそのままにしても一応安全
2023/01/08(日) 22:52:59.71ID:9eCFH/Xi
818追記
コピー元が空になっても構わないならVec::appendで同じことができる
2023/01/08(日) 23:03:17.84ID:OD5QAUK5
>>817-819
ありがと。試してみます

エクスプローラーから同ドライブへのコピーで数秒ってところでしょうか
2023/01/09(月) 00:21:25.60ID:L9fsJfRH
>>812
1000個のファイルで1秒だと、もともとOSの速度がその程度の場合も有り得そう。
1ファイル当り1(ms)ということになるから。
もともとファイルはそこまで一度に沢山の個数をopen, closeすることは
想定されて無いので。
それもRustの安全機構が遅さに影響を与えているかも。
2023/01/09(月) 00:26:23.50ID:L9fsJfRH
>>821
ファイルって、例えばファイラーでコピーする場合でも、合計が同じ容量でも、
細かいファイルが多数有る場合の方がずっと遅くなる。
一個の1MBのファイルをコピーすると一瞬なのに、1KBの1000個のファイルをコピー
すると1秒くらい掛かるかも。
823デフォルトの名無しさん
垢版 |
2023/01/09(月) 01:18:38.59ID:1jv8LwEE
profilingしてsyscallがボトルネックになってれば非同期や並列化で高速化するしかない
2023/01/09(月) 10:40:30.18ID:qWwsdzcu
たとえどんなにメモリ確保が遅くともディスクIOよりも遅いってことはないだろう
体感の遅さが何秒とかじゃなくてドライブのベンチマークと比べて判断しよう
2023/01/09(月) 10:58:52.04ID:SSufLxQW
>>820
エクスプローラーってことはWindows?
そもそもWindowsはファイルシステムのsyscallが結構重いから
メモリコピーとか関係なくそんなものの可能性はあるかと
思い込みで試行錯誤してないでちゃんとプロファイル取ったほうがいいよ
2023/01/09(月) 15:14:46.56ID:eWb8PeTD
cargo testでドキュメントテストが実行されないんだけどお前らも同じ?
ドキュメントに書いてある通りに実行してるけど実行されない
2023/01/09(月) 15:29:11.68ID:Tw59sECy
>>826
普通に実行されるから doctest の書き方間違えてるんじゃないのかなぁ
`(バッククォート) じゃなくて '(シングルクォート) になってるとか
2023/01/09(月) 15:35:17.32ID:eWb8PeTD
>>827
ああ、すみません。解決しました。
どうもバイナリだと実行されないみたいです。

cargo new myprog

で作成したバイナリだと駄目で

cargo new doclib --lib

で作成したライブラリではちゃんと実行されました。
2023/01/09(月) 15:52:28.38ID:Tw59sECy
>>828
おお、本当ですね... なんでこういう動きなんだろう、分かる人いないかな?
2023/01/09(月) 17:51:48.91ID:ytPnwm3y
Rust固有の話でもないんだけどUnicode対応のアーカイブフォーマットってどんなのがあるんだろ
比較的新しい7zipはUnicodeファイル名をサポートしているけどライブラリやクレートが豊富とはいいがたい
かといってレガシーなzipやtarだとファイル名のコーディングは実装依存にみえる
実装依存の場合Unicodeファイル名をサポートしているライブラリやクレートがあるのかという問題も出てくるし
2023/01/09(月) 19:37:23.02ID:ytPnwm3y
tarで実験していたら詰んだw
let mut v:Vec<u8> = Vec::new();
let mut c = std::io::Cursor::new(v);
let mut t = tar::Builder::new(c);
t.append_path("foo.txt");
std::fs::write("foo.tar", &v); // borrow of moved value: `v`
どうしろと・・・
2023/01/09(月) 19:48:59.36ID:qp/cfIgC
>>830
zip も特定のビットを立てていればファイル名が UTF-8 ということになる。
https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.10.TXT
項目 4.4.4 で説明されている Bit 11 を見て。
2023/01/09(月) 19:50:26.02ID:FCxfWiS9
>>831
なにがしたいんこれ
2023/01/09(月) 20:12:49.13ID:NBV9jC+W
mut大好きそう
2023/01/09(月) 20:21:20.61ID:ytPnwm3y
>>833
オンメモリでtarを作って出来上がったものをファイルに保存したい
2023/01/09(月) 20:46:41.39ID:vdwHQqNl
tar使ったことないけどt.get_ref().get_ref()で&Vec<u8>取り出せるのかな
先にt.finish()呼ぶべきかもしれないしget_refよりinto_innerの方がいいかもしれない

get_refは詰み回避の頻出手筋
2023/01/09(月) 21:28:27.40ID:ytPnwm3y
>>836
let a = t.get_ref().get_ref();
std::fs::write("foo.tar", a);
これは一応それっぽいファイルが作られた

let mut a = t.into_inner().unwrap();
let mut f = std::fs::File::create("foo.tar").unwrap();
std::io::copy(&mut a, &mut f);
こっちは空っぽだった

ttps://crates.io/crates/tar
こんなサンプルしかないしCursorを使用する例なんて見当たらないし
どうやるのが妥当なのか全くわからん
2023/01/09(月) 22:00:04.05ID:ytPnwm3y
ttps://docs.rs/tar/latest/tar/struct.Builder.html#method.append_path
>pub fn append_path<P: AsRef<Path>>(&mut self, path: P) -> Result<()>
>~
>Also note that after all files have been written to an archive the finish function needs to be called to finish writing the archive.
らしいが
>pub fn finish(&mut self) -> Result<()>
>~
>In most situations the into_inner method should be preferred.
どっちなんだよw
ここに載っているサンプルだってinto_innerもfinishも呼んでいないのがあるし
2023/01/09(月) 23:33:14.26ID:2xcnkP4M
>>835
もう解決してそうだけど
let mut c = ...からt.append_path(...)までを別スコープにすれば通らない?
2023/01/10(火) 00:39:55.01ID:j3UGlM4K
>>837
空っぽになるのはtarのinto_innerでfinish経由でwrite_allが呼ばれて
cursorのpositionが末尾になっててio::copy時には書き出すものがないから
2023/01/10(火) 00:49:25.83ID:j3UGlM4K
t.append_pathしたタイミングでcursor.position進んでたわ
そりゃそうか
2023/01/10(火) 01:07:25.76ID:LMu5FpAe
let mut v = Vec::new();
let c = std::io::Cursor::new(&mut v);
let mut t = tar::Builder::new(c);
t.append_path("foo.txt");
t.finish();
drop(t);
std::fs::write("foo.tar", &v);
843デフォルトの名無しさん
垢版 |
2023/01/10(火) 01:15:57.75ID:MfXPDJ7e
get_mutでCursorにすればReaderとして使える
2023/01/10(火) 02:21:46.49ID:UwgiY8HJ
そのコードでCursor使う意味が分からん
let mut tar = tar::Builder::new(Vec::new());
tar.append_path("foo.txt").unwrap();
let body = tar.into_inner().unwrap();
std::fs::write("foo.tar", body).unwrap();
845デフォルトの名無しさん
垢版 |
2023/01/10(火) 03:54:21.65ID:jTn98fgX
昨日のファイル1000個の続きなんじゃね
メモリに全部読読み込んでから処理しようとする理由は謎
2023/01/10(火) 11:07:15.73ID:UY3YN64G
The Bookをやり終えたあとってどうするのがいい?
次に読むべきおすすめの書籍があるか知りたいです!
847デフォルトの名無しさん
垢版 |
2023/01/10(火) 13:00:32.37ID:wZlueyRK
>>846
次の書籍を読む前にThe Bookの復習がてら簡単なCLIツールを3~5個くらい書いて自分の理解を確かめたほうがいいよ
2023/01/10(火) 16:48:39.24ID:UY3YN64G
>>847
アドバイスありがとうございます!
とりあえず何かしら作ってみようと思います
849デフォルトの名無しさん
垢版 |
2023/01/10(火) 17:29:32.58ID:0JcDinm0
コマンドラインに渡した(1000個の)ファイルを
指定した名前のtarファイルに書き出すツールとか
2023/01/10(火) 18:47:02.53ID:jt9UZCSx
>>845
メモリを事前に一括で確保してVecの逐次伸長をなくせば早くなるんじゃね?
と思ったけど実験してみたら全くそんなことはなかった。Rustのメモリアロケータって優秀なんだな・・・
2023/01/10(火) 19:01:05.30ID:ICakwhma
何使ってんのかな
mallocかな
852デフォルトの名無しさん
垢版 |
2023/01/10(火) 21:06:19.40ID:doG42uyJ
10回程度の小さい容量のアロケートなんてI/Oに比べれば微々たるものでしょ
2023/01/11(水) 14:35:14.84ID:PmiCGwmF
Vecのcapacityって再確保のたびに倍々に増えていくんじゃなかったっけ
ならpushの回数を増やしても再確保回数は大した数字にならないだろう
2023/01/11(水) 19:26:52.32ID:STTwcLZn
ドライブレターを割り当ててあるネットワークドライブのパスを
dunce::canonicalizeに食わせるとUNCパスが返ってくる
そりゃねーぜ・・・
855デフォルトの名無しさん
垢版 |
2023/01/11(水) 21:38:38.39ID:+7dhpYN+
こういう瑣末な問題を自分で解決する力のない人はまだRustを使うべき時期じゃないよね
2023/01/11(水) 23:08:05.53ID:STTwcLZn
というかLinuxのProtonだとネットワークドライブへのアクセスでも
ドライブレタースタートのパスが返ってくるのな
結果、Windowsだと動かないけどLinuxなら動くという珍事になってるw
857デフォルトの名無しさん
垢版 |
2023/01/12(木) 09:12:37.07ID:KDs8BtvS
ファイル属性の取得はファイル読み込みよりは圧倒的に速いので
・ファイル名とファイルサイズの取得
・合計サイズのチェックと領域の確保
の順でやればマシかもね
ファイル読み込みに比べたら微々たる違いだとは思うが
858デフォルトの名無しさん
垢版 |
2023/01/12(木) 10:55:41.76ID:YWq2QOJT
ファイルの数だけ二重にsyscallを呼び出すことになるからサイズのデカい数ファイルを処理するときならともかく1000ファイルで合計1MBという今回のケースだと悪化するんじゃね?
2023/01/12(木) 11:13:05.66ID:CILc6G1+
ripgrepの実装でも見た方が早そう
2023/01/12(木) 11:37:44.42ID:Iq4TKL6o
>>858
そもそもトータル1MB程度って分かってるなら余裕みて2MB程度確保しとけば良いような気がするが...
861デフォルトの名無しさん
垢版 |
2023/01/12(木) 12:26:48.24ID:lE5eokgZ
>>859
ripgrepは今回のようにすべてのコンテンツを全て一括でメモリに保持するわけじゃないから
streamingで処理するのでいいなら固定長のバッファ確保してそこを使いながらパイプライン通して結果をI/O出力すればいい

>>860
アロケーションがボトルネックならそういう対処もあるだろうけど十中八九違うんじゃね?
2023/01/12(木) 13:42:55.06ID:xHtWNAJz
は?頭悪いの?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況