我有一个应用程序需要将文件传输到像 S3 这样的服务。
我有一个InputStream
传入文件(不一定是 a FileInputStream
),我将其写入InputStream
由 a 表示的多部分请求正文,OutputStream
然后我需要在末尾写入文件的哈希(也通过请求正文)。
多亏了DigestInputStream
,我能够实时计算散列,因此在将文件主体发送到 之后OutputStream
,散列变得可用并且也可以附加到多部分请求中。
你可以检查这个相关的问题: 什么是更便宜的哈希算法?
特别是我自己的基准答案: https ://stackoverflow.com/a/19160508/82609
因此,我自己的计算机似乎能够以MessageDigest
500MB/s 的 MD5 吞吐量和近 200MB/s 的 SHA-512 吞吐量进行散列。
我写入请求正文的连接的吞吐量为 100MB/s。如果我以更高的吞吐量写入 OutputStream,OutputStream 开始阻塞(这是故意这样做的,因为我们确实希望保持较低的内存占用并且不希望字节在应用程序的某些部分累积)
我已经完成了测试,我可以清楚地注意到算法对我的应用程序性能的影响。
我尝试上传 20 个 50MB 的文件(总共 1Gb)。
- 使用 MD5,大约需要 16 秒
- 使用 SHA-512,大约需要 22 秒
在进行单次上传时,我还可以看到相同顺序的减速。
所以最后没有并行计算哈希和写入连接:这些步骤是按顺序完成的:
- 从流中请求字节
- 散列请求的字节
- 发送字节
因此,由于散列的吞吐量 > 连接吞吐量,有没有一种简单的方法可以不减慢速度?它需要额外的线程吗?
我认为下一个数据块可以在前一个块被写入连接期间被预先计算和散列,对吗?
这不是一个过早的优化,我们需要上传很多文件,执行时间对我们的业务来说是明智的。