跳到内容

性能

Node.js 在处理对原生模块(如 sharp)的异步调用时使用 libuv 管理的线程池。

sharp 可以并行处理的最大图像数量由 libuv 的 UV_THREADPOOL_SIZE 环境变量控制,默认值为 4。

当使用超过 4 个物理 CPU 核心时,应在 Node.js 进程启动前设置此环境变量,以增加线程池大小。

Terminal window
export UV_THREADPOOL_SIZE="$(lscpu -p | egrep -v "^#" | sort -u -t, -k 2,4 | wc -l)"

libvips 使用 glib 管理的线程池来避免频繁创建新线程带来的开销。

默认用于并发处理每张图像的线程数与 CPU 核心数量相同, 但在使用基于 glibc 的 Linux 且未使用 jemalloc 的情况下,默认线程数为 1,以帮助减少内存碎片。

可使用 sharp.concurrency() 来管理每张图像的线程数。

在使用默认的 Linux glibc 内存分配器时,为减少内存碎片, 应在 Node.js 进程启动前设置 MALLOC_ARENA_MAX 环境变量以减少内存池数量。

Terminal window
export MALLOC_ARENA_MAX="2"

一个用来比较本模块与其他替代方案性能的测试。

启用缓存(默认)且使用 8 核以上机器时,可以预期 libvips 性能更佳, 尤其是具有较大 L1/L2 CPU 缓存的机器。

相关(解)压缩库的 I/O 限制通常决定最大吞吐量。

  • jimp v1.6.0 - 纯 JavaScript 图像处理。
  • imagemagick v0.1.3 - 仅支持文件系统,且“已经很长时间没有维护”。
  • gm v1.25.1 - 功能完整的 GraphicsMagick gm 命令行工具封装库,但“已被废弃”。
  • sharp v0.34.0 / libvips v8.16.1 - 关闭 libvips 缓存,以保证测试的公平性。

解压一张 2725x2225 的 JPEG 图像, 使用 Lanczos 3 重采样(可用时)调整大小为 720x588, 然后以“质量”为 80 压缩成 JPEG。

注意:jimp 不支持 Lanczos 3,改用双三次(bicubic)重采样。

模块输入输出ops/秒加速
jimpbufferbuffer2.351.0
imagemagickfilefile10.514.5
gmbufferbuffer11.675.0
gmfilefile11.755.1
sharpstreamstream60.7225.8
sharpfilefile62.3726.5
sharpbufferbuffer65.1527.7
模块输入输出ops/秒加速
jimpbufferbuffer2.131.0
imagemagickfilefile12.956.1
gmbufferbuffer13.536.4
gmfilefile13.526.4
sharpstreamstream46.5821.9
sharpfilefile48.4222.7
sharpbufferbuffer50.1623.6

解压一张 2048x1536 的 RGBA PNG 图像, 对 alpha 通道进行预乘, 使用 Lanczos 3 重采样(可用时)调整大小为 720x540, 取消预乘后以 PNG 格式压缩,使用默认 zlib 压缩等级(6),且不启用自适应滤波。

注意:jimp 不支持预乘和取消预乘。

模块输入输出ops/秒加速
gmfilefile8.661.0
imagemagickfilefile8.791.0
jimpbufferbuffer11.261.3
sharpfilefile27.933.2
sharpbufferbuffer28.693.3
模块输入输出ops/秒加速
gmfilefile9.651.0
imagemagickfilefile9.721.0
jimpbufferbuffer10.681.1
sharpfilefile23.902.5
sharpbufferbuffer24.482.5

需要 Docker。

Terminal window
git clone https://github.com/lovell/sharp.git
cd sharp/test/bench
./run-with-docker.sh