浏览器处理Base64数据的极限速度大比拼

本文深入探讨了现代浏览器中JavaScript内置Base64编码和解码函数的性能表现,通过对Safari、Chrome、Firefox等多款浏览器的实际测试,揭示了不同浏览器内核在处理Base64数据时的速度差异和底层实现原理。

Base64是一种二进制到文本的编码方案,它将任意二进制数据(如图像、文件或任何字节序列)转换成一个安全的、可打印的ASCII字符串,使用的是包含64个字符的字母表(A–Z、a–z、0–9、+、/)。浏览器在JavaScript中使用它,以便在代码或HTML中直接嵌入二进制数据,或者将二进制数据作为文本传输。

浏览器最近添加了方便且安全的函数来处理base64:Uint8Array.toBase64()Uint8Array.fromBase64()。尽管它们有几个参数,但归结起来就是一个编码函数和一个解码函数。

1
2
const b64 = Base64.toBase64(bytes);      // 字符串
const recovered = Base64.fromBase64(b64); // Uint8Array

编码时,它从输入中获取24位。这24位被分成四个6位的段,每个6位值(范围从0到63)被映射到Base64字母表中的一个特定字符:前26个字符是大写字母A-Z,接着26个是小写字母a-z,然后是数字0-9,最后是+/作为第62和63个字符。当输入长度不是3字节的倍数时,等号=用作填充。

它们的速度有多快?

假设每个CPU周期消耗3字节并产生4字节。以4.5 GHz的频率计算,Base64的编码速度将达到13.5 GB/s。我们预期反方向的解码性能会更低。编码时,任何输入都是有效的:任何二进制数据都可以。然而,解码时,我们必须处理错误并跳过空格。

我编写了一个浏览器内基准测试。你可以在你喜欢的浏览器中试试看。

我决定在我的苹果M4处理器上测试,看看各种浏览器的速度如何。我使用了64 KiB的块。速度是相对于二进制数据来测量的。

浏览器 编码速度 解码速度
Safari 17 GB/s 9.4 GB/s
SigmaOS 17 GB/s 9.4 GB/s
Chrome 19 GB/s 4.6 GB/s
Edge 19 GB/s 4.6 GB/s
Brave 19 GB/s 4.6 GB/s
Servo 0.34 GB/s 0.40 GB/s
Firefox 0.34 GB/s 0.40 GB/s

Safari的编码速度似乎比基于Chromium的浏览器(Chrome、Edge、Brave)略慢,但其解码速度大约是前者的两倍。Servo和Firefox的性能同样较差,并且出现了意想不到的结果:解码速度比编码速度更快。我本可以尝试其他浏览器,但大多数似乎都是Chromium或WebKit的衍生品。

作为背景参考,一台好笔记本电脑的磁盘可以持续超过3 GB/s的读取或写入速度。一些高端笔记本电脑的磁盘速度超过5 GB/s。理论上,你的Wi-Fi连接在Wi-Fi 7标准下可能接近5 GB/s。一些互联网提供商可能提供接近类似速度的网络连接,尽管你的互联网连接很可能要慢好几倍。

大多数浏览器的速度比你最初猜测的要快。它们比网络或磁盘的速度更快。

注意:基于Chromium的浏览器解码速度较慢,似乎取决于v8 JavaScript引擎,该引擎会先将字符串解码到一个临时缓冲区,然后才从临时缓冲区复制到最终目的地。(参见v8源代码src/builtins/builtins-typed-array.cc中的BUILTIN(Uint8ArrayFromBase64)。)

注意:来自Mozilla的Denis Palmeiro告知我,Firefox即将进行的更改将提高base64函数的性能。在我使用Firefox Nightly版本的测试中,性能提升了大约20%。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计