simdutf:每秒数十亿个字符的 Unicode 验证和转码


大多数现代软件都依赖于Unicode 标准。在内存中,Unicode 字符串使用 UTF-8 或 UTF-16 表示。UTF-8 格式是网络上事实上的标准(JSON、HTML 等),并且已被许多流行编程语言(Go、Rust、Swift 等)采用为默认格式。UTF-16 格式是 Java、C# 和许多 Windows 技术中的标准。

并非所有字节序列都是有效的 Unicode 字符串。在没有首先验证它们的情况下,在 UTF-8 和 UTF-16LE 中使用 Unicode 字符串是不安全的。此外,我们经常需要通过称为转码的过程将字符串从一种编码转换为另一种编码。出于安全目的,此类转码应该进行验证:它应该拒绝对不正确的字符串进行转码。

simdutf 库的用途是:

  • Node.js(19.4.0 或更高版本、20.0 或更高版本、18.15 或更高版本),标准 JavaScript 运行时环境,
  • Bun,一个快速的 JavaScript 运行环境,
  • graaljs,Oracle 的 JavaScript 实现,
  • Couchbase,
  • haskell/text,一个用于快速操作 Unicode 文本的库,
  • klogg,一个非常快的日志浏览器,
  • Pixie,Kubernetes 应用程序的可观察性工具。

流行的 Node.js JavaScript 运行时采用 simdutf 库带来了显着的性能提升:
解码和编码变得比 Node.js 18 快得多。通过添加用于 UTF-8 解析观察到的基准的 simdutf,与 Node.js 16 相比,解码时的结果提高了 364%

该库会自动检测您的处理器并选择最合适的函数“内核”。它支持多种指令集(ARM NEON、SSE2、AVX2),但直到去年,它还不支持 AVX-512。

使用 AVX-512 转换(或“转码”)字符串的速度有多快?
这是一篇新论文的主题:使用 AVX-512 指令转码 unicode 字符

在最新的 Intel 和 AMD 处理器上使用 AVX-512,从 UTF-8 转码时,我们在中文和表情符号输入上的速度超过 4 GB/s,在阿拉伯文本上几乎达到 8 GB/s。从 UTF-16 转码时,中文和表情符号文本的速度超过了 5 GB/s,阿拉伯语文本的速度突破了 20 GB/s 的障碍。

支持 AVX-512 的旧版英特尔处理器由于各种形式的“频率限制”而引发了严重的担忧:每当您使用这些指令时,它们都会触发频率降低。因此,我们不在这些较旧的处理器上使用 AVX-512 指令,而是转而使用 AVX 指令。由于 AVX-512 指令,AMD Zen 4 或最新的英特尔处理器上没有频率限制。

该库提供快速的 Unicode 函数,例如

  • ASCII、UTF-8、UTF-16LE/BE 和 UTF-32 验证,带或不带错误识别,
  • Latin1 到 UTF-8 转码,
  • Latin1 到 UTF-16LE/BE 转码
  • Latin1 到 UTF-32 转码
  • UTF-8 到 Latin1 转码,带或不带验证,带或不带错误识别,
  • UTF-8 到 UTF-16LE/BE 转码,带或不带验证,带或不带错误识别,
  • UTF-8 到 UTF-32 转码,带或不带验证,带或不带错误识别,
  • UTF-16LE/BE 到 Latin1 转码,带或不带验证,带或不带错误识别,
  • UTF-16LE/BE 到 UTF-8 转码,带或不带验证,带或不带错误识别,
  • UTF-32 到 Latin1 转码,带或不带验证,带或不带错误识别,
  • UTF-32 到 UTF-8 转码,带或不带验证,带或不带错误识别,
  • UTF-32 到 UTF-16LE/BE 转码,带或不带验证,带或不带错误识别,
  • UTF-16LE/BE 到 UTF-32 转码,带或不带验证,带或不带错误识别,
  • 根据 UTF-8 字符串,计算 Latin1 等效字符串的大小,
  • 从 UTF-8 字符串计算 UTF-16 等效字符串的大小,
  • 从 UTF-8 字符串计算 UTF-32 等效字符串的大小(相当于 UTF-8 字符计数),
  • 从 UTF-16LE/BE 字符串计算 Latin1 等效字符串的大小,
  • 从 UTF-16LE/BE 字符串计算 UTF-8 等效字符串的大小,
  • 从 UTF-32 字符串计算 UTF-8 或 UTF-16LE 等效字符串的大小,
  • 从 UTF-16LE/BE 字符串计算 UTF-32 等效字符串的大小(相当于 UTF-16 字符计数),
  • UTF-8 和 UTF-16LE/BE 字符计数。
  • UTF-16 字节顺序更改(UTF16-LE/BE 至 UTF-16-BE/LE)

使用SIMD指令(例如ARM NEON、SSE、AVX、AVX-512等)加速功能。当您的字符串包含数百个字符时,我们通常可以以超过每秒十亿个字符的速度对它们进行转码。您不仅可以期待英文字符串 (ASCII) 的高速运行,还可以期待中文、日文、阿拉伯文等的高速运行。我们处理完整的字符范围(包括表情符号)。

该库编译为一个几百千字节的小库。我们的函数是无异常且非分配的。我们有广泛的测试和广泛的基准。