Skip to content

性能

¥Parallelism and concurrency

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

¥Node.js uses a libuv-managed thread pool when processing asynchronous calls to native modules such as sharp.

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

¥The maximum number of images that sharp can process in parallel is controlled by libuv’s UV_THREADPOOL_SIZE environment variable, which defaults to 4.

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

¥When using more than 4 physical CPU cores, set this environment variable before the Node.js process starts to increase the thread pool size.

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

libvips 使用 glib 管理的线程池来避免生成新线程的开销。

¥libvips uses a glib-managed thread pool to avoid the overhead of spawning new threads.

用于并发处理每个图片的默认线程数与 CPU 核心数相同,但使用基于 glibc 且不使用 jemalloc 的 Linux 系统除外,此时默认线程数为 1,以帮助减少内存碎片。

¥The default number of threads used to concurrently process each image is the same as the number of CPU cores, except when using glibc-based Linux without jemalloc, where the default is 1 to help reduce memory fragmentation.

使用 sharp.concurrency() 管理每幅图片的线程数。

¥Use sharp.concurrency() to manage the number of threads per image.

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

¥To reduce memory fragmentation when using the default Linux glibc memory allocator, set the MALLOC_ARENA_MAX environment variable before the Node.js process starts to reduce the number of memory pools.

Terminal window
export MALLOC_ARENA_MAX="2"

¥Benchmark

对该模块相对于替代方案的性能进行基准测试。

¥A test to benchmark the performance of this module relative to alternatives.

启用缓存(默认)并使用 8 个以上核心的计算机(尤其是具有较大 L1/L2 CPU 缓存的计算机)可以期待更高的 libvips 性能。

¥Greater libvips performance can be expected with caching enabled (default) and using 8+ core machines, especially those with larger L1/L2 CPU caches.

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

¥The I/O limits of the relevant (de)compression library will generally determine maximum throughput.

¥Contenders

  • jimp v1.6.0 - 纯 JavaScript 中的图片处理。

    ¥jimp v1.6.0 - Image processing in pure JavaScript.

  • imagemagick v0.1.3 - 仅支持文件系统和 “has been unmaintained for a long time”。

    ¥imagemagick v0.1.3 - Supports filesystem only and “has been unmaintained for a long time”.

  • gm v1.25.1 - GraphicsMagick 的 gm 命令行实用程序的全功能封装器,但 “已停用”。

    ¥gm v1.25.1 - Fully featured wrapper around GraphicsMagick’s gm command line utility, but “has been sunset”.

  • sharp v0.34.3 / libvips v8.17.0 - 禁用 libvips 内的缓存以确保公平比较。

    ¥sharp v0.34.3 / libvips v8.17.0 - Caching within libvips disabled to ensure a fair comparison.

¥Environment

  • AWS EC2 us-west-2 c7a.xlarge (4x AMD EPYC 9R14)

  • Ubuntu 25.04

  • Node.js 24.3.0

  • AWS EC2 us-west-2 c8g.xlarge (4x ARM Graviton4)

  • Ubuntu 25.04

  • Node.js 24.3.0

¥Task: JPEG

解压缩 2725x2225 JPEG 图片,使用 Lanczos 3 重采样(如果可用)将大小调整为 720x588,然后以 “quality” 设置 80 压缩为 JPEG。

¥Decompress a 2725x2225 JPEG image, resize to 720x588 using Lanczos 3 resampling (where available), then compress to JPEG at a “quality” setting of 80.

注意:jimp 不支持 Lanczos 3,而是使用双三次重采样。

¥Note: jimp does not support Lanczos 3, bicubic resampling used instead.

¥Results: JPEG (AMD64)

I/O操作数/秒加速
jimpbuffer2.401.0
jimpfile2.601.1
imagemagickfile9.704.0
gmbuffer11.604.8
gmfile11.724.9
sharpstream59.4024.8
sharpfile62.6726.1
sharpbuffer64.4226.8

¥Results: JPEG (ARM64)

I/O操作数/秒加速
jimpbuffer2.241.0
jimpfile2.471.1
imagemagickfile10.424.7
gmbuffer12.805.7
gmfile12.885.7
sharpstream45.5820.3
sharpfile47.9921.4
sharpbuffer49.2022.0

¥Task: PNG

解压缩 2048x1536 RGBA PNG 图片,预乘 Alpha 通道,使用 Lanczos 3 重采样(如果可用)将大小调整为 720x540,取消预乘,然后使用 “default” zlib 压缩级别 6 压缩为 PNG,并且不使用自适应滤波。

¥Decompress a 2048x1536 RGBA PNG image, premultiply the alpha channel, resize to 720x540 using Lanczos 3 resampling (where available), unpremultiply then compress as PNG with a “default” zlib compression level of 6 and without adaptive filtering.

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

¥Note: jimp does not support premultiply/unpremultiply.

¥Results: PNG (AMD64)

I/O操作数/秒加速
imagemagickfile6.061.0
gmfile8.441.4
jimpbuffer10.981.8
sharpfile28.264.7
sharpbuffer28.704.7

¥Results: PNG (ARM64)

I/O操作数/秒加速
imagemagickfile7.091.0
gmfile8.931.3
jimpbuffer10.281.5
sharpfile23.813.4
sharpbuffer24.193.4

¥Running the benchmark test

需要 Docker。

¥Requires Docker.

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