JavaScript中MD5计算的预期性能是什么?

5

我正在尝试使用JavaScript计算MD5,并查看 Stack Overflow 帖子中的'JKM'实现是较快的实现之一。我正在使用基于JKM实现的SparkMD5。然而,所提供的示例https://github.com/satazor/SparkMD5/blob/master/test/readme_example.html对于一个13MB的文件需要约10秒钟的时间(使用调试器则需要23秒),而相同的文件在linux命令行中使用md5sum函数只需要0.03秒钟的时间。这些结果对于JavaScript实现来说是否太慢了,还是这个性能表现很差是可以预期的?

1个回答

8

预计的。

首先,我认为我不需要告诉你JAVASCRIPT很慢。是的,即使使用现代的JIT优化等技术,JavaScript仍然很慢。

为了向您展示这不是您的JS实现的问题,我将与Node.js进行一些比较,以便浏览器DOM内容不会妨碍基准测试。

测试文件生成:

$ dd if=/dev/zero of=file bs=6M count=1

我的服务器只有512 MB的RAM,而Node.js无法使用超过6M的内存。
脚本:
//var md5 = require('crypto-js/md5')
var md5 = require('MD5')
//var md5 = require('spark-md5').hash
//var md5 = require('blueimp-md5').md5

require('fs').readFile('file', 'utf8', function(e, b) {  // Using string here to be fair for all md5 engines
  console.log(md5(b))
})

(你可以取消注释参赛者/基准)

结果如下:(去除文件读取开销)

  • MD5: 5.250秒 - 0.072秒 = 5.178秒
  • crypto-js/md5: 4.914秒 - 0.072秒 = 4.842秒
  • Blueimp: 4.904秒 - 0.072秒 = 4.832秒
  • 使用Node.js二进制缓冲区而非字符串的MD5: 1.143秒 - 0.063秒 = 1.080秒
  • spark: 0.311秒 - 0.072秒 = 0.239秒
  • md5sum: 0.023秒 - 0.003秒 = 0.020秒

因此,实际上,spark-md5并不差。

当查看示例HTML页面时,我发现它们正在使用增量API。所以我又做了一个基准测试:

var md5 = require('spark-md5')

var md5obj = new md5()
var chunkNum = 0

require('fs').createReadStream('file')
  .on('data', function (b) {
    chunkNum ++
    md5obj.append(b.toString())
  })
  .on('end', function () {
    console.log('total ' + chunkNum + ' chunks')
    console.log(md5obj.end())
  })

使用96个块,时间为0.313秒。

所以,实际上并不是MD5实现的问题。性能如此之差有点让人惊讶,但在浏览器中运行此代码并非完全不可能。

顺便说一句,我的服务器是DigitalOcean VPS,带有SSD。文件读取开销约为0.072秒:

require('fs').readFile('file', 'utf8', function() {})

使用本地cat时,时间约为0.003秒。

对于使用本地Buffer的MD5,开销约为0.063秒:

require('fs').readFile('file', function() {})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接