ファイルを S3 などのサービスに転送する必要があるアプリケーションがあります。
InputStream
その着信ファイル (必ずしも a である必要はありません)FileInputStream
があり、これInputStream
を で表されるマルチパート リクエスト ボディOutputStream
に書き込みます。次に、ファイルのハッシュを最後に (これもリクエスト ボディを介して) 書き込む必要があります。
のおかげでDigestInputStream
、ハッシュをライブで計算できるので、ファイル本体が に送信されたOutputStream
後、ハッシュが利用可能になり、マルチパート リクエストに追加することもできます。
この関連する質問を確認できます: 最も安価なハッシュ アルゴリズムとは何ですか?
特に私自身のベンチマークの回答: https://stackoverflow.com/a/19160508/82609
したがって、私のコンピューターはMessageDigest
、MD5 で 500MB/秒、SHA-512 で 200MB/秒近くのスループットでハッシュできるようです。
リクエスト本文を書き込む接続のスループットは 100MB/s です。より高いスループットで OutputStream に書き込むと、OutputStream がブロックされ始めます (これは、メモリ フットプリントを低く保ち、アプリケーションの一部にバイトを蓄積させたくないため、意図的に行われます)。
テストを行ったところ、アルゴリズムがアプリケーションのパフォーマンスに与える影響がはっきりとわかりました。
50MB (合計 1Gb) のファイルを 20 個アップロードしようとしました。
- MD5 では、約 16 秒かかります
- SHA-512 の場合、約 22 秒かかります
単一のアップロードを実行すると、同じ順序で速度が低下することもわかります。
したがって、最終的には、ハッシュの計算と接続への書き込みの並列化はありません。これらのステップは順番に実行されます。
- ストリームからバイトを要求する
- 要求されたバイトのハッシュ
- バイトの送信
ハッシュのスループットは接続スループットよりも大きいため、その速度低下を回避する簡単な方法はありますか? 追加のスレッドが必要ですか?
前のチャンクが接続に書き込まれている間に、データの次のチャンクを事前に計算してハッシュできると思いますか?
これは時期尚早の最適化ではありません。大量のドキュメントをアップロードする必要があり、実行時間はビジネスにとって妥当です。