ushitora-anqou/zipar https://github.com/ushitora-anqou/zipar
雑に動かしたら zip(1) よりも 2.7 倍速かった。
こういう感じに高速に Zip アーカイブ作ってくれるくんが本当に他にないのか、かなり疑っています。
@anqou 超定番ツール・実装にさくっと大差で勝つの、すごすぎて笑いました。すごい。
先行実装、雑にググりました。ぜひ評価して、勝ってください! https://github.com/jpakkane/parzip
@tadd ありがとうございます!!! 多分中でやってること同じな気がするので勝てなさそうです(まだ動かしてませんが)
@tadd あ、一応誤解のないように説明しておくと、これは圧縮**しない** ZIP アーカイブならファイルの構造がすぐ確定するので並列でファイルがコピーできて速い、みたいな原理です。
@anqou なるほどなるほどー。逆方向の展開ツール(John the RipperのOMP版)ですが、ファイル構造からして並列化大変、みたいなコメントがありました。
@tadd そうなんですよね、ZIP のフォーマット的に、ファイルの一番うしろに central directory を持っていて、ファイルへのオフセットをいい感じに保存する必要があるので、並列にするのはかなり面倒そうです。
@anqou なるほど、リンカーぽい……?(Linkers & Loadersを読んでない人並の感想)
@tadd 実際めっちゃリンカーっぽいと思います(自分も Linkers&Loaders は読んでない)
@anqou 全く分かってなくて適当なことを言いますが、一番最後、というのがまだ救いな気がしました。もし個々をMapできればReduceのタイミングでできそうというか、Promise.allをawaitしたらフッタを書けそうというか。
やはりまったく分かっていない自分……
@tadd いえ、多分お察しの通りで、ファイル各々を並列で圧縮したあとなら各ファイルがどこに配置されるかわかるので、それを詰め込む(reduce する)だけでいいはずです。いま parzip の実装を読んでいたのですが、まさにそういう形の実装になっていそうで、ここで並列に圧縮して
https://github.com/jpakkane/parzip/blob/8fa591e3ac8e2fcce0791b5494913f3bd7cde6a2/src/zipcreator.cpp#L311
ファイルへの書き込み自体はここで直列になっていそうでした:
https://github.com/jpakkane/parzip/blob/8fa591e3ac8e2fcce0791b5494913f3bd7cde6a2/src/zipcreator.cpp#L355
今回自分が作ったのは圧縮の部分が無い代わりにファイルへの書き込みが並列になるという作りなので、(初めメンションをもらったときに同じ作りだと言ってしまいましたが)結構アイデアレベルで違う作りでした。
それはそれとして、この parzip の仕組みだと圧縮したファイルのデータをどこかに持っておかないといけない(一般的には RAM に乗りきらないのでファイルとかに書き出さないといけない?)はずで(そこまで読み込めていませんが)、inplace な実装は難しいだろうなぁみたいな雑な気持ちがあります。関連する話題としては、gzip で圧縮したファイルを zip ファイルに固めなおすときに解凍しなくていみたいな話があって、これもある意味並列で圧縮した gz ファイルをシリアルに zip に固め直すみたいな話と似たような話だなーとか考えています。(話にまとまりがなくてすいません)
https://knqyf263.hatenablog.com/entry/2022/03/10/091150
@anqou なるほどなるほどー。ファイルの書き込みが並列に行けるの、いいですね。(固定ビットレートのMP3もきっとそう)
あとまとまりなくて全然OKです。こういうのむっちゃ好きです、楽しいですよね。一局面でも定番(や定番同士の連携)に一矢報いるの、かっこいいじゃないですか。好きな惣菜過ぎました。
@tadd ありがとうございます、そういってもらえるとめちゃ嬉しいです!
@tadd 買います!!!
@anqou 書いてから気付いたのですが釈迦に説法感が……某御社の方も寄稿なさってました
@tadd いえいえ、以前から存在は知っていたんですけど予約するのを忘れていたので、さっき予約しました。