溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用wasm+js實現(xiàn)文件獲取md5

發(fā)布時間:2022-08-09 13:58:22 來源:億速云 閱讀:260 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“怎么使用wasm+js實現(xiàn)文件獲取md5”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

準(zhǔn)備工作

通過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計算結(jié)束,因為現(xiàn)實中,我們需要做loading條動畫比例

  • mac 2.7 GHz 雙核Intel Core i5

  • mac 8 GB 1867 MHz DDR3

測試目標(biāo)

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); // 執(zhí)行 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>

測試結(jié)論

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,分段要快一些

最終結(jié)論

  • chrome對js的優(yōu)化,使得在600M-1024M期間的大文件純js計算md5速度要快于wasm,其他范圍還是wasm性能好一些

  • 由于firefox超過1G就崩潰了,所以我們平時寫代碼時,還是要做分段加載的。

  • 業(yè)務(wù)中,還是可以使用wasm來提升性能的

  • 可以針對 chrome與其他瀏覽器來制作不同的方案

  • 其實golang 計算md5基本上是js的7-9倍,但js給wasm復(fù)制數(shù)據(jù)的時間占用了太多,導(dǎo)致wasm被降低了速度,文件越大,復(fù)制時間越長,越慢

wasm 還是可以使用的,眾觀全局,速度提升2-3倍。chrome可以針對性處理

“怎么使用wasm+js實現(xiàn)文件獲取md5”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI