WebP 并行压缩效率对比

最近实现了一个基于 Tauri 的 WebP 图片压缩软件,压缩的软件功能由 Rust 实现,比很多现行的图像压缩软件快得多。但是 Rust 究竟给软件的效率作出了多少贡献?为了解开这个疑惑,我用几种不同的语言编写了并行压缩图像到 WebP 并保存的命令行工具,测试这些语言在这项任务中的效率。

构建命令行工具的代码如项目 Repo 中所示,使用的语言包括 PythonJavascriptGoRust。这些命令行工具均接受三个参数:

  • --input-dir <dir>:输入图片所在的文件夹;
  • --quality <number>:WebP 压缩质量分;
  • --output-dir <dir>:输出图片的文件夹。

测试环境

  • 系统参数
    • CPU:AMD R5-5600
    • Windows10:22H2 19045.4651
    • WSL:Ubuntu 24.04 LTS
  • 测试输入
    • 输入图片:3000 张 PNG 图片,分辨率 1280x1856
    • 压缩质量:90

测试结果

语言 用时/s - Windows 10 用时/s - WSL 补充
Python 101.48 155.60 Python==3.11.7(Win)/3.12.3(WSL), Pillow==9.5.0
Node.js 182.90 388.56 Node==20.15.0(Win)/18.19.1(WSL), Sharp==0.33.4
Rust 87.63 99.50 rustc==1.79.0, webp==0.3.0, image==0.25.1, rayon==1.10.0
Go 160.93 go==1.22.2, go-webp==1.0.4
  • 在测试时,除了 Nodejs,其它语言均在运行时使 CPU 满载,因此应当可以忽略磁盘 IO 等其它因素对效率的影响。
  • 检查了输出文件内容,发现数据完全相同,应当是调用了相同的方法对图片进行有损压缩(大概都来自 libwebp)。

讨论和结论

  • Python 虽然是解释型语言,不过调用的库内部效率很高,总体效率直逼编译型语言(实际上已经超过了 Go);
  • Nodejs 的 Workers 调用不太方便,似乎也不太适合做高 IO、高计算负载的工作,是唯一一个在测试时没有让 CPU 满载的;
  • Rust 虽然语法严格,不过在各种包的帮助下开发并不困难,效率也是最高的。在 WSL 环境下,性能损失也比其它语言更小;
  • Go 官方提供的 webp 库只能解码图像,而社区提供的 go-webp 库在编译时需要 libwebp,在 Windows 上难以配置,因此只在 WSL 上编译并测试。然而却出乎意料地相当慢(即使使用了 -ldflags "-s -w"),可能是库的优化问题?

看来使用 Rust 库是相当正确的决策。通过这项测试,发现 Rust 在处理高 IO 和 CPU 密集型任务,如图像压缩时,展现出了卓越的性能。Rust 不仅在 Windows 系统上性能优异,在 WSL 环境下相较于其他语言也显示出较小的性能损失,这证明了其稳定性和高效性。

Python 是一个解释型语言,它通常不会被认为是性能最优的选择,特别是在需要大量计算和数据处理的场景中。然而,通过使用经过良好优化的第三方库,Python 也能在处理重负载任务时展现出令人惊讶的高性能,其中的一些库甚至能与编译型语言如 C++ 和 Rust 的性能相媲美。考虑到 Python 在开发效率上的额外优势,在一些快速开发工作中,编写 Python 脚本处理数据也是一个不错的选择。