温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么使用wasm+js实现文件获取md5

发布时间:2022-08-09 13:58:22 来源:亿速云 阅读:264 作者:iii 栏目:开发技术

本篇内容介绍了“怎么使用wasm+js实现文件获取md5”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

准备工作

通过ffmeg 从一个2G+的文件上截取不同体积的文件,用于测试。

ffmpeg -i /path/sourch.mp4  -fs 1M -c:v copy -c:a copy /path/1M.mp4
ffmpeg -i /path/sourch.mp4  -fs 5M -c:v copy -c:a copy /path/5M.mp4
ffmpeg -i /path/sourch.mp4  -fs 20M -c:v copy -c:a copy /path/20M.mp4
ffmpeg -i /path/sourch.mp4  -fs 50M -c:v copy -c:a copy /path/50M.mp4
ffmpeg -i /path/sourch.mp4  -fs 100M -c:v copy -c:a copy /path/100M.mp4
ffmpeg -i /path/sourch.mp4  -fs 200M -c:v copy -c:a copy /path/200M.mp4
ffmpeg -i /path/sourch.mp4  -fs 400M -c:v copy -c:a copy /path/400M.mp4
ffmpeg -i /path/sourch.mp4  -fs 600M -c:v copy -c:a copy /path/500M.mp4
ffmpeg -i /path/sourch.mp4  -fs 800M -c:v copy -c:a copy /path/800M.mp4
ffmpeg -i /path/sourch.mp4  -fs 900M -c:v copy -c:a copy /path/900M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1024M -c:v copy -c:a copy /path/1024M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1280M -c:v copy -c:a copy /path/1280M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1536M -c:v copy -c:a copy /path/1536M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1792M -c:v copy -c:a copy /path/1792M.mp4
ffmpeg -i /path/sourch.mp4  -fs 2048M -c:v copy -c:a copy /path/2048M.mp4

测试代码

纯js测试代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./SparkMD5.js"></script>
</head>
<body>
  <input id="file" type="file" />
  <script>
    document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      const md5 = new SparkMD5();
      fileReader.readAsBinaryString(file);
      fileReader.onload = e => {
        md5.appendBinary(e.target.result);
        const md5Str = md5.end()
        usedTime += Date.now() - startTime
        console.log('usedTime', usedTime, 'ms')
        console.log('md5', md5Str)
      }
    });
  </script>
</body>
</html>

wasm(go)源码

请参考:

github.com/butoften/wa&hellip;

js+wasm测试代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./wasm_exec.js"></script>
</head>
<body>
  <script>
    function handleSayHello(message) {
      console.lof('str from go', message)
    }
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch('wasm/md5.wasm'), go.importObject)
      .then(res => {
        go.run(res.instance);
      });
  </script>
  <input id="file" type="file" />
  <script>
    document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      fileReader.readAsArrayBuffer(file);
      fileReader.onload = e => {
        const bytes = new Uint8Array(e.target.result)
        wasmMd5Add(bytes)
        const md5Hash = wasmMd5End()
        usedTime += Date.now() - startTime
        console.log('usedTime', usedTime, 'ms')
        console.log('md5', md5Hash)
      }
    });
  </script>
</body>
</html>

测试条件

  • 从FileReader开始读取算起到md5计算结束,因为现实中,我们需要做loading条动画比例

  • mac 2.7 GHz 双核Intel Core i5

  • mac 8 GB 1867 MHz DDR3

测试目标

chrome (版本:103.0.5060.114)

  • 2048M 测试5次分别用时:

  • 如果分段计算,每段使用512M

序号纯js纯js分段js+wasmjs+wasm分段
137477 ms25638 ms31680 ms22898 ms
232926 ms28088 ms32516 ms25168 ms
333413 ms31412 ms33424 ms20547 ms
435054 ms35821 ms33906 ms23130 ms
535986 ms36895 ms29014 ms22011 ms
  • 1792M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
116298 ms19441 ms27322 ms19233 ms
211593 ms29424 ms28955 ms18602 ms
324589 ms28685 ms28192 ms18472 ms
424725 ms29892 ms28931 ms18260 ms
524695 ms31453 ms36166 ms19474 ms
  • 1536M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
119856 ms19591 ms21259 ms15920 ms
215119 ms26283 ms20821 ms15634 ms
321387 ms25861 ms22473 ms16893 ms
419550 ms25797 ms21793 ms17239 ms
520363 ms26402 ms20782 ms15786 ms
  • 1280M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
16449 ms12169 ms22856 ms16621 ms
214695 ms17558 ms19147 ms18014 ms
317792 ms20326 ms17203 ms14683 ms
418094 ms16452 ms18396 ms14399 ms
515830 ms19006 ms19241 ms14119 ms
  • 1024M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
15003 ms9441 ms16233 ms9252 ms
26240 ms14917 ms11145 ms9316 ms
38563 ms10849 ms12653 ms10963 ms
410261 ms12155 ms11607 ms9108 ms
58775 ms11138 ms9869 ms10451 ms
  • 900M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
14632 ms7721 ms9590 ms7887 ms
25858 ms3312 ms7161 ms7963 ms
32859 ms10808 ms7646 ms7973 ms
43531 ms8614 ms7904 ms8197 ms
55744 ms7612 ms7131 ms10714 ms
  • 800M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
13329 ms5884 ms9318 ms7270 ms
27222 ms9917 ms6897 ms7096 ms
32602 ms6066 ms6295 ms6908 ms
42757 ms6662 ms6551 ms8164 ms
52509 ms8730 ms7126 ms7039 ms
  • 600M 测试5次分别用时:

序号纯js纯js分段js+wasmjs+wasm分段
12721 ms2824 ms6557 ms5019 ms
23241 ms6867 ms4943 ms5026 ms
31803 ms3012 ms4902 ms5052 ms
41930 ms3010 ms5007 ms5022 ms
51807 ms2885 ms4881 ms5238 ms
  • 400M 测试5次分别用时:

序号纯jsjs+wasm
16406 ms3358 ms
26435 ms3599 ms
36450 ms3283 ms
46286 ms3952 ms
56408 ms3207 ms
  • 200M 测试5次分别用时:

序号纯jsjs+wasm
13497 ms1705 ms
23412 ms1643 ms
33263 ms1825 ms
43284 ms1710 ms
53376 ms1768 ms
  • 100M 测试5次分别用时:

序号纯jsjs+wasm
11873 ms923 ms
21776 ms928 ms
31772 ms913 ms
41682 ms923 ms
51742 ms898 ms
  • 50M 测试5次分别用时:

序号纯jsjs+wasm
11043 ms516 ms
2877 ms479 ms
3907 ms504 ms
4872 ms459 ms
5865 ms495 ms
  • 20M 测试5次分别用时:

序号纯jsjs+wasm
1487 ms209 ms
2387 ms209 ms
3410 ms225 ms
4512 ms268 ms
5399 ms225 ms
  • 5M 测试10次分别用时:

序号纯jsjs+wasm
1147 ms92 ms
2133 ms90 ms
3177 ms94 ms
4157 ms42 ms
5175 ms84 ms
  • 1M 测试5次分别用时:

序号纯jsjs+wasm
171 ms20 ms
266 ms24 ms
345 ms33 ms
480 ms30 ms
597 ms29 ms

firefox (版本号:103.0.1 (64 位))

  • 2048M 加载到52%时页面崩溃

    • 采用Blob.slice方式分段计算

    • 每512M为一段,测试5次

序号纯js分段js+wasm分段
151398 ms17338 ms
241282 ms16385 ms
342358 ms16966 ms
443363 ms15843 ms
540802 ms16551 ms
  • 1792M 加载到59%时页面崩溃

    • 采用Blob.slice方式分段计算

    • 每512M为一段,测试5次

序号纯js分段js+wasm分段
133690 ms13251 ms
237423 ms13636 ms
342903 ms13487 ms
432684 ms13662 ms
536691 ms14984 ms
  • 1536M 加载到69%时页面崩溃

    • 采用Blob.slice方式分段计算

    • 每512M为一段,测试5次

序号纯js分段js+wasm分段
128051 ms11425 ms
227822 ms11337 ms
328331 ms12508 ms
430089 ms11520 ms
532890 ms11507 ms
  • 1280M 加载到83%时页面崩溃

    • 采用Blob.slice方式分段

    • 计算512M为一段

序号纯js分段js+wasm分段
125680 ms9571 ms
223956 ms9549 ms
328829 ms10070 ms
423518 ms9449 ms
523200 ms9540 ms
  • 1024M 测试10次分别用时:

序号纯jsjs+wasm
138277 ms7776 ms
240936 ms11254 ms
329861 ms7653 ms
425630 ms7517 ms
518934 ms11443 ms
624849 ms8039 ms
718214 ms7727 ms
818617 ms12987 ms
933281 ms7523 ms
1040757 ms8895 ms
  • 900M 测试10次分别用时:

序号纯jsjs+wasm
122752 ms8605 ms
216669 ms9313 ms
315716 ms6678 ms
416940 ms6521 ms
516732 ms9269 ms
615805 ms6582 ms
715718 ms6519 ms
815795 ms9377 ms
915641 ms6773 ms
1015622 ms7489 ms
  • 800M 测试10次分别用时:

序号纯jsjs+wasm
115181 ms8333 ms
214031 ms5880 ms
314214 ms5987 ms
433812 ms5935 ms
514167 ms8666 ms
614666 ms8031 ms
728640 ms5991 ms
813992 ms5840 ms
913926 ms6032 ms
1014216 ms6637 ms
  • 600M 测试10次分别用时:

序号纯jsjs+wasm
111418 ms4457 ms
211199 ms5370 ms
310717 ms4654 ms
410607 ms4436 ms
510611 ms4479 ms
610718 ms4368 ms
710560 ms5494 ms
811519 ms5044 ms
910802 ms4426 ms
1011779 ms4971 ms
  • 400M 测试10次分别用时:

序号纯jsjs+wasm
18362 ms2981 ms
27516 ms2999 ms
37335 ms3030 ms
47357 ms3150 ms
57444 ms3001 ms
68456 ms3223 ms
77376 ms3120 ms
87313 ms3072 ms
97349 ms3240 ms
107447 ms3352 ms
  • 200M 测试10次分别用时:

序号纯jsjs+wasm
14066 ms1525 ms
24440 ms1516 ms
34223 ms1510 ms
43916 ms1610 ms
53917 ms1509 ms
64028 ms1588 ms
73964 ms1514 ms
84037 ms1507 ms
93957 ms1506 ms
103987 ms1642 ms
  • 100M 测试10次分别用时:

序号纯jsjs+wasm
12280 ms761 ms
22331 ms820 ms
32193 ms798 ms
42242 ms777 ms
52197 ms752 ms
62330 ms769 ms
72236 ms758 ms
82364 ms798 ms
92278 ms783 ms
102384 ms785 ms
  • 50M 测试10次分别用时:

序号纯jsjs+wasm
11366 ms397 ms
21355 ms378 ms
31445 ms460 ms
41468 ms437 ms
51417 ms406 ms
61525 ms478 ms
71381 ms393 ms
81450 ms430 ms
91417 ms428 ms
101378 ms431 ms
  • 20M 测试10次分别用时:

序号纯jsjs+wasm
1921 ms168 ms
2871 ms162 ms
3859 ms163 ms
4864 ms162 ms
51025 ms177 ms
6910 ms158 ms
7904 ms150 ms
8931 ms187 ms
91014 ms182 ms
10871 ms159 ms
  • 5M 测试10次分别用时:

序号纯jsjs+wasm
1127 ms48 ms
2124 ms50 ms
3140 ms44 ms
4129 ms47 ms
5127 ms51 ms
6129 ms50 ms
7126 ms46 ms
8119 ms54 ms
9121 ms46 ms
10118 ms50 ms
  • 1M 测试10次分别用时:

序号纯jsjs+wasm
146 ms18 ms
241 ms22 ms
343 ms13 ms
440 ms15 ms
544 ms11 ms
647 ms15 ms
742 ms11 ms
842 ms20 ms
945 ms13 ms
1044 ms16 ms

分段计算测试代码

纯js

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./SparkMD5.js"></script>
</head>
<body>
  <input id="file" type="file" />
  <script>
  document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      const md5 = new SparkMD5();
      let index = 0
      const chunkSize = 512 * 1024 * 1024;//file.size / count
      let count = Math.ceil(file.size / chunkSize)
      console.log('分几份', count)
      loadSliceFile();
      function loadSliceFile() {
        const sliceFile = file.slice(index * chunkSize, index * chunkSize + chunkSize)
        fileReader.readAsBinaryString(sliceFile);
      }
      fileReader.onload = e => {
        index += 1;
        md5.appendBinary(e.target.result);
        if (index < count) {
          loadSliceFile()
        }
        else {
          const md5Str = md5.end()
          usedTime += Date.now() - startTime
          console.log('usedTime', usedTime, 'ms')
          console.log('md5', md5Str)
        }
      }
    });
  </script>
</body>
</html>

js+wasm

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./wasm_exec.js"></script>
  <!-- <script src="./wasm_exec_tiny.js"></script> -->
</head>
<body>
  <script>
    function handleSayHello(message) {
      console.lof('str from go', message)
    }
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch('wasm/md5.wasm'), go.importObject)
      .then(res => {
        go.run(res.instance); // 执行 golang里 main 方法
      });
  </script>
  <input id="file" type="file" />
  <script>
    document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      let index = 0
      const sliceSize = 512
      const chunkSize = sliceSize * 1024 * 1024;//file.size / count
      let count = Math.ceil(file.size / chunkSize)
      console.log('分几份', count)
      loadSliceFile();
      function loadSliceFile() {
        const sliceFile = file.slice(index * chunkSize, index * chunkSize + chunkSize)
        fileReader.readAsArrayBuffer(sliceFile);
      }
      fileReader.onload = e => {
        index += 1;
        const bytes = new Uint8Array(e.target.result)
        wasmMd5Add(bytes)
        if (index < count) {
          loadSliceFile()
        }
        else {
          const md5Hash = wasmMd5End()
          usedTime += Date.now() - startTime
          console.log('usedTime', usedTime, 'ms')
          console.log('md5', md5Hash)
        }
      }
    });
  </script>
</body>
</html>

测试结论

firefox

  • 超过1G的文件,直接崩溃,只能通过分段计算最终合并计算

  • 从1M到2G,wasm的速度是纯js计算的2-3倍

  • 20M,wasm是纯js的 6倍

chrome

  • 0-400M时,wasm是纯js的2-3倍

  • 600M-1024M时,纯js不分段比wasm要快

    • 分段js比不分段wasm快一点点

    • 分段js比分段wasm慢一点点

  • 1280M,差不太多

  • 大于1280M,js比wasm分段慢

  • 对于js,分段要慢一些

  • 对于wasm,分段要快一些

最终结论

  • chrome对js的优化,使得在600M-1024M期间的大文件纯js计算md5速度要快于wasm,其他范围还是wasm性能好一些

  • 由于firefox超过1G就崩溃了,所以我们平时写代码时,还是要做分段加载的。

  • 业务中,还是可以使用wasm来提升性能的

  • 可以针对 chrome与其他浏览器来制作不同的方案

  • 其实golang 计算md5基本上是js的7-9倍,但js给wasm复制数据的时间占用了太多,导致wasm被降低了速度,文件越大,复制时间越长,越慢

wasm 还是可以使用的,众观全局,速度提升2-3倍。chrome可以针对性处理

“怎么使用wasm+js实现文件获取md5”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI