diff --git a/test/bench/Dockerfile b/test/bench/Dockerfile index 19066592..63ad36fd 100644 --- a/test/bench/Dockerfile +++ b/test/bench/Dockerfile @@ -1,14 +1,13 @@ -FROM ubuntu:23.10 +FROM ubuntu:24.10 ARG BRANCH=main # Install basic dependencies RUN apt-get -y update && apt-get install -y build-essential curl git ca-certificates gnupg # Install latest Node.js LTS -RUN mkdir -p /etc/apt/keyrings -RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list -RUN apt-get -y update && apt-get install -y nodejs +RUN curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh +RUN bash nodesource_setup.sh +RUN apt-get install -y nodejs # Install benchmark dependencies RUN apt-get install -y imagemagick libmagick++-dev graphicsmagick @@ -26,8 +25,4 @@ RUN node -v WORKDIR /tmp/sharp/test/bench -# Workaround for: https://github.com/emscripten-core/emscripten/pull/16917 -# This could be removed once Squoosh is an optional dependency. -ENV NODE_OPTIONS="--no-experimental-fetch" - CMD [ "node", "perf" ] diff --git a/test/bench/package.json b/test/bench/package.json index fb00437e..e6a97a4f 100644 --- a/test/bench/package.json +++ b/test/bench/package.json @@ -8,16 +8,14 @@ "test": "node perf && node random && node parallel" }, "dependencies": { - "@squoosh/cli": "0.7.3", - "@squoosh/lib": "0.5.3", - "async": "3.2.5", + "async": "3.2.6", "benchmark": "2.1.4", - "gm": "1.25.0", + "gm": "1.25.1", "imagemagick": "0.1.3", - "jimp": "0.22.10" + "jimp": "1.6.0" }, "optionalDependencies": { - "@tensorflow/tfjs-node": "4.13.0", + "@tensorflow/tfjs-node": "4.22.0", "mapnik": "4.5.9" }, "license": "Apache-2.0" diff --git a/test/bench/perf.js b/test/bench/perf.js index 4941f855..a973f7a7 100644 --- a/test/bench/perf.js +++ b/test/bench/perf.js @@ -3,9 +3,8 @@ 'use strict'; -const os = require('os'); const fs = require('fs'); -const { exec, execSync } = require('child_process'); +const { execSync } = require('child_process'); const async = require('async'); const Benchmark = require('benchmark'); @@ -22,8 +21,8 @@ const sharp = require('../../'); const gm = require('gm'); const imagemagick = require('imagemagick'); const mapnik = safeRequire('mapnik'); -const jimp = require('jimp'); -const squoosh = require('@squoosh/lib'); +const { Jimp, JimpMime } = require('jimp'); + process.env.TF_CPP_MIN_LOG_LEVEL = 1; const tfjs = safeRequire('@tensorflow/tfjs-node'); @@ -52,102 +51,21 @@ async.series({ // jimp jpegSuite.add('jimp-buffer-buffer', { defer: true, - fn: function (deferred) { - jimp.read(inputJpgBuffer, function (err, image) { - if (err) { - throw err; - } else { - image - .resize(width, height, jimp.RESIZE_BICUBIC) - .quality(80) - .getBuffer(jimp.MIME_JPEG, function (err) { - if (err) { - throw err; - } else { - deferred.resolve(); - } - }); - } - }); + fn: async function (deferred) { + const image = await Jimp.read(inputJpgBuffer) + await image + .resize({ w: width, h: height, mode: Jimp.RESIZE_BICUBIC }) + .getBuffer(JimpMime.jpeg, { quality: 80 }); + deferred.resolve(); } }).add('jimp-file-file', { defer: true, - fn: function (deferred) { - jimp.read(fixtures.inputJpg, function (err, image) { - if (err) { - throw err; - } else { - image - .resize(width, height, jimp.RESIZE_BICUBIC) - .quality(80) - .write(outputJpg, function (err) { - if (err) { - throw err; - } else { - deferred.resolve(); - } - }); - } - }); - } - }); - // squoosh-cli - jpegSuite.add('squoosh-cli-file-file', { - defer: true, - fn: function (deferred) { - exec(`./node_modules/.bin/squoosh-cli \ - --output-dir ${os.tmpdir()} \ - --resize '{"enabled":true,"width":${width},"height":${height},"method":"lanczos3","premultiply":false,"linearRGB":false}' \ - --mozjpeg '{"quality":80,"progressive":false,"optimize_coding":true,"quant_table":0,"trellis_multipass":false,"chroma_subsample":2,"separate_chroma_quality":false}' \ - "${fixtures.inputJpg}"`, function (err) { - if (err) { - throw err; - } - deferred.resolve(); - }); - } - }); - // squoosh-lib (GPLv3) - jpegSuite.add('squoosh-lib-buffer-buffer', { - defer: true, - fn: function (deferred) { - const pool = new squoosh.ImagePool(os.cpus().length); - const image = pool.ingestImage(inputJpgBuffer); - image.decoded - .then(function () { - return image.preprocess({ - resize: { - enabled: true, - width, - height, - method: 'lanczos3', - premultiply: false, - linearRGB: false - } - }); - }) - .then(function () { - return image.encode({ - mozjpeg: { - quality: 80, - progressive: false, - optimize_coding: true, - quant_table: 0, - trellis_multipass: false, - chroma_subsample: 2, - separate_chroma_quality: false - } - }); - }) - .then(function () { - return pool.close(); - }) - .then(function () { - return image.encodedWith.mozjpeg; - }) - .then(function () { - deferred.resolve(); - }); + fn: async function (deferred) { + const image = await Jimp.read(fixtures.inputJpg); + await image + .resize({ w: width, h: height, mode: Jimp.RESIZE_BICUBIC }) + .getBuffer(JimpMime.jpeg, { quality: 80 }); + deferred.resolve(); } }); // mapnik @@ -648,98 +566,21 @@ async.series({ // jimp pngSuite.add('jimp-buffer-buffer', { defer: true, - fn: function (deferred) { - jimp.read(inputPngBuffer, function (err, image) { - if (err) { - throw err; - } else { - image - .resize(width, heightPng, jimp.RESIZE_BICUBIC) - .deflateLevel(6) - .filterType(0) - .getBuffer(jimp.MIME_PNG, function (err) { - if (err) { - throw err; - } else { - deferred.resolve(); - } - }); - } - }); + fn: async function (deferred) { + const image = await Jimp.read(inputPngBuffer); + await image + .resize({ w: width, h: heightPng, mode: Jimp.RESIZE_BICUBIC }) + .getBuffer(JimpMime.png, { deflateLevel: 6, filterType: 0 }); + deferred.resolve(); } }).add('jimp-file-file', { defer: true, - fn: function (deferred) { - jimp.read(fixtures.inputPngAlphaPremultiplicationLarge, function (err, image) { - if (err) { - throw err; - } else { - image - .resize(width, heightPng, jimp.RESIZE_BICUBIC) - .deflateLevel(6) - .filterType(0) - .write(outputPng, function (err) { - if (err) { - throw err; - } else { - deferred.resolve(); - } - }); - } - }); - } - }); - // squoosh-cli - pngSuite.add('squoosh-cli-file-file', { - defer: true, - fn: function (deferred) { - exec(`./node_modules/.bin/squoosh-cli \ - --output-dir ${os.tmpdir()} \ - --resize '{"enabled":true,"width":${width},"height":${heightPng},"method":"lanczos3","premultiply":true,"linearRGB":false}' \ - --oxipng '{"level":1}' \ - "${fixtures.inputPngAlphaPremultiplicationLarge}"`, function (err) { - if (err) { - throw err; - } - deferred.resolve(); - }); - } - }); - // squoosh-lib (GPLv3) - pngSuite.add('squoosh-lib-buffer-buffer', { - defer: true, - fn: function (deferred) { - const pool = new squoosh.ImagePool(os.cpus().length); - const image = pool.ingestImage(inputPngBuffer); - image.decoded - .then(function () { - return image.preprocess({ - resize: { - enabled: true, - width, - height: heightPng, - method: 'lanczos3', - premultiply: true, - linearRGB: false - } - }); - }) - .then(function () { - return image.encode({ - oxipng: { - level: 1 - } - }); - }) - .then(function () { - return pool.close(); - }) - .then(function () { - return image.encodedWith.oxipng; - }) - .then(function () { - deferred.resolve(); - }); + fn: async function (deferred) { + const image = await Jimp.read(fixtures.inputPngAlphaPremultiplicationLarge) + await image + .resize({ w: width, h: heightPng, mode: Jimp.RESIZE_BICUBIC }) + .write(outputPng, { deflateLevel: 6, filterType: 0 }); + deferred.resolve(); } }); // mapnik