mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Update benchmark results ahead of v0.21.0
Remove lwip and images as they lack Node 10 support
This commit is contained in:
parent
c22e2a17ef
commit
1565e58fcf
@ -3,19 +3,17 @@
|
|||||||
### Test environment
|
### Test environment
|
||||||
|
|
||||||
* AWS EC2 eu-west-1 [c5.large](https://aws.amazon.com/ec2/instance-types/c5/) (2x Xeon Platinum 8124M CPU @ 3.00GHz)
|
* AWS EC2 eu-west-1 [c5.large](https://aws.amazon.com/ec2/instance-types/c5/) (2x Xeon Platinum 8124M CPU @ 3.00GHz)
|
||||||
* Ubuntu 17.10 (hvm:ebs-ssd, 20180102, ami-0741d47e)
|
* Ubuntu 18.04 (hvm-ssd/ubuntu-bionic-18.04-amd64-server-20180912 ami-00035f41c82244dab)
|
||||||
* Node.js v8.9.4
|
* Node.js v10.11.0
|
||||||
|
|
||||||
### The contenders
|
### The contenders
|
||||||
|
|
||||||
* [jimp](https://www.npmjs.com/package/jimp) v0.2.28 - Image processing in pure JavaScript. Bilinear interpolation only.
|
* [jimp](https://www.npmjs.com/package/jimp) v0.5.3 - Image processing in pure JavaScript. Provides bicubic interpolation.
|
||||||
* [pajk-lwip](https://www.npmjs.com/package/pajk-lwip) v0.2.0 (fork) - Wrapper around CImg that compiles dependencies from source.
|
* [mapnik](https://www.npmjs.org/package/mapnik) v4.0.1 - Whilst primarily a map renderer, Mapnik contains bitmap image utilities.
|
||||||
* [mapnik](https://www.npmjs.org/package/mapnik) v3.6.2 - Whilst primarily a map renderer, Mapnik contains bitmap image utilities.
|
|
||||||
* [imagemagick-native](https://www.npmjs.com/package/imagemagick-native) v1.9.3 - Wrapper around libmagick++, supports Buffers only.
|
* [imagemagick-native](https://www.npmjs.com/package/imagemagick-native) v1.9.3 - Wrapper around libmagick++, supports Buffers only.
|
||||||
* [imagemagick](https://www.npmjs.com/package/imagemagick) v0.1.3 - Supports filesystem only and "*has been unmaintained for a long time*".
|
* [imagemagick](https://www.npmjs.com/package/imagemagick) v0.1.3 - Supports filesystem only and "*has been unmaintained for a long time*".
|
||||||
* [gm](https://www.npmjs.com/package/gm) v1.23.1 - Fully featured wrapper around GraphicsMagick's `gm` command line utility.
|
* [gm](https://www.npmjs.com/package/gm) v1.23.1 - Fully featured wrapper around GraphicsMagick's `gm` command line utility.
|
||||||
* [images](https://www.npmjs.com/package/images) v3.0.1 - Compiles dependencies from source. Provides bicubic interpolation.
|
* sharp v0.21.0 / libvips v8.7.0 - Caching within libvips disabled to ensure a fair comparison.
|
||||||
* sharp v0.19.0 / libvips v8.6.1 - Caching within libvips disabled to ensure a fair comparison.
|
|
||||||
|
|
||||||
### The task
|
### The task
|
||||||
|
|
||||||
@ -27,19 +25,14 @@ then compress to JPEG at a "quality" setting of 80.
|
|||||||
|
|
||||||
| Module | Input | Output | Ops/sec | Speed-up |
|
| Module | Input | Output | Ops/sec | Speed-up |
|
||||||
| :----------------- | :----- | :----- | ------: | -------: |
|
| :----------------- | :----- | :----- | ------: | -------: |
|
||||||
| jimp (bilinear) | buffer | buffer | 1.14 | 1.0 |
|
| jimp | buffer | buffer | 0.71 | 1.0 |
|
||||||
| lwip | buffer | buffer | 1.86 | 1.6 |
|
| mapnik | buffer | buffer | 3.32 | 4.7 |
|
||||||
| mapnik | buffer | buffer | 3.34 | 2.9 |
|
| gm | buffer | buffer | 3.97 | 5.6 |
|
||||||
| imagemagick-native | buffer | buffer | 4.13 | 3.6 |
|
| imagemagick-native | buffer | buffer | 4.06 | 5.7 |
|
||||||
| gm | buffer | buffer | 4.21 | 3.7 |
|
| imagemagick | file | file | 4.24 | 6.0 |
|
||||||
| gm | file | file | 4.27 | 3.7 |
|
| sharp | stream | stream | 25.30 | 35.6 |
|
||||||
| imagemagick | file | file | 4.67 | 4.1 |
|
| sharp | file | file | 26.17 | 36.9 |
|
||||||
| images (bicubic) | file | file | 6.22 | 5.5 |
|
| sharp | buffer | buffer | 26.45 | 37.3 |
|
||||||
| sharp | stream | stream | 24.43 | 21.4 |
|
|
||||||
| sharp | file | file | 25.97 | 22.7 |
|
|
||||||
| sharp | file | buffer | 26.00 | 22.8 |
|
|
||||||
| sharp | buffer | file | 26.33 | 23.0 |
|
|
||||||
| sharp | buffer | buffer | 26.43 | 23.1 |
|
|
||||||
|
|
||||||
Greater libvips performance can be expected with caching enabled (default)
|
Greater libvips performance can be expected with caching enabled (default)
|
||||||
and using 8+ core machines, especially those with larger L1/L2 CPU caches.
|
and using 8+ core machines, especially those with larger L1/L2 CPU caches.
|
||||||
@ -57,7 +50,7 @@ brew install mapnik
|
|||||||
```
|
```
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt-get install imagemagick libmagick++-dev graphicsmagick mapnik-dev
|
sudo apt-get install imagemagick libmagick++-dev graphicsmagick libmapnik-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -13,10 +13,8 @@
|
|||||||
"gm": "^1.23.1",
|
"gm": "^1.23.1",
|
||||||
"imagemagick": "^0.1.3",
|
"imagemagick": "^0.1.3",
|
||||||
"imagemagick-native": "^1.9.3",
|
"imagemagick-native": "^1.9.3",
|
||||||
"images": "^3.0.1",
|
|
||||||
"jimp": "^0.5.3",
|
"jimp": "^0.5.3",
|
||||||
"mapnik": "^4.0.1",
|
"mapnik": "^4.0.1",
|
||||||
"pajk-lwip": "^0.2.0",
|
|
||||||
"semver": "^5.5.1"
|
"semver": "^5.5.1"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
@ -12,24 +12,12 @@ const gm = require('gm');
|
|||||||
const imagemagick = require('imagemagick');
|
const imagemagick = require('imagemagick');
|
||||||
const mapnik = require('mapnik');
|
const mapnik = require('mapnik');
|
||||||
const jimp = require('jimp');
|
const jimp = require('jimp');
|
||||||
let images;
|
|
||||||
try {
|
|
||||||
images = require('images');
|
|
||||||
} catch (err) {
|
|
||||||
console.log('Excluding node-images');
|
|
||||||
}
|
|
||||||
let imagemagickNative;
|
let imagemagickNative;
|
||||||
try {
|
try {
|
||||||
imagemagickNative = require('imagemagick-native');
|
imagemagickNative = require('imagemagick-native');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Excluding imagemagick-native');
|
console.log('Excluding imagemagick-native');
|
||||||
}
|
}
|
||||||
let lwip;
|
|
||||||
try {
|
|
||||||
lwip = require('pajk-lwip');
|
|
||||||
} catch (err) {
|
|
||||||
console.log('Excluding lwip');
|
|
||||||
}
|
|
||||||
|
|
||||||
const fixtures = require('../fixtures');
|
const fixtures = require('../fixtures');
|
||||||
|
|
||||||
@ -38,8 +26,6 @@ const height = 588;
|
|||||||
|
|
||||||
// Disable libvips cache to ensure tests are as fair as they can be
|
// Disable libvips cache to ensure tests are as fair as they can be
|
||||||
sharp.cache(false);
|
sharp.cache(false);
|
||||||
// Enable use of SIMD
|
|
||||||
sharp.simd(true);
|
|
||||||
|
|
||||||
async.series({
|
async.series({
|
||||||
'jpeg': function (callback) {
|
'jpeg': function (callback) {
|
||||||
@ -87,51 +73,6 @@ async.series({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// lwip
|
|
||||||
if (typeof lwip !== 'undefined') {
|
|
||||||
jpegSuite.add('lwip-file-file', {
|
|
||||||
defer: true,
|
|
||||||
fn: function (deferred) {
|
|
||||||
lwip.open(fixtures.inputJpg, function (err, image) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
image.resize(width, height, 'lanczos', function (err, image) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
image.writeFile(fixtures.outputJpg, {quality: 80}, function (err) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
deferred.resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).add('lwip-buffer-buffer', {
|
|
||||||
defer: true,
|
|
||||||
fn: function (deferred) {
|
|
||||||
lwip.open(inputJpgBuffer, 'jpg', function (err, image) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
image.resize(width, height, 'lanczos', function (err, image) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
image.toBuffer('jpg', {quality: 80}, function (err, buffer) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
assert.notStrictEqual(null, buffer);
|
|
||||||
deferred.resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// mapnik
|
// mapnik
|
||||||
jpegSuite.add('mapnik-file-file', {
|
jpegSuite.add('mapnik-file-file', {
|
||||||
defer: true,
|
defer: true,
|
||||||
@ -272,14 +213,6 @@ async.series({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// images
|
|
||||||
if (typeof images !== 'undefined') {
|
|
||||||
jpegSuite.add('images-file-file', function () {
|
|
||||||
images(fixtures.inputJpg)
|
|
||||||
.resize(width, height)
|
|
||||||
.save(fixtures.outputJpg, { quality: 80 });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// sharp
|
// sharp
|
||||||
jpegSuite.add('sharp-buffer-file', {
|
jpegSuite.add('sharp-buffer-file', {
|
||||||
defer: true,
|
defer: true,
|
||||||
@ -569,8 +502,10 @@ async.series({
|
|||||||
defer: true,
|
defer: true,
|
||||||
fn: function (deferred) {
|
fn: function (deferred) {
|
||||||
sharp(inputJpgBuffer)
|
sharp(inputJpgBuffer)
|
||||||
.resize(width, height)
|
.resize(width, height, {
|
||||||
.crop(sharp.strategy.entropy)
|
fit: 'cover',
|
||||||
|
position: sharp.strategy.entropy
|
||||||
|
})
|
||||||
.toBuffer(function (err, buffer) {
|
.toBuffer(function (err, buffer) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
@ -584,8 +519,10 @@ async.series({
|
|||||||
defer: true,
|
defer: true,
|
||||||
fn: function (deferred) {
|
fn: function (deferred) {
|
||||||
sharp(inputJpgBuffer)
|
sharp(inputJpgBuffer)
|
||||||
.resize(width, height)
|
.resize(width, height, {
|
||||||
.crop(sharp.strategy.attention)
|
fit: 'cover',
|
||||||
|
position: sharp.strategy.attention
|
||||||
|
})
|
||||||
.toBuffer(function (err, buffer) {
|
.toBuffer(function (err, buffer) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
@ -696,31 +633,6 @@ async.series({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// lwip
|
|
||||||
if (typeof lwip !== 'undefined') {
|
|
||||||
pngSuite.add('lwip-buffer-buffer', {
|
|
||||||
defer: true,
|
|
||||||
fn: function (deferred) {
|
|
||||||
lwip.open(inputPngBuffer, 'png', function (err, image) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
image.resize(width, height, 'lanczos', function (err, image) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
image.toBuffer('png', function (err, buffer) {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
assert.notStrictEqual(null, buffer);
|
|
||||||
deferred.resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// mapnik
|
// mapnik
|
||||||
pngSuite.add('mapnik-file-file', {
|
pngSuite.add('mapnik-file-file', {
|
||||||
defer: true,
|
defer: true,
|
||||||
@ -833,14 +745,6 @@ async.series({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// images
|
|
||||||
if (typeof images !== 'undefined') {
|
|
||||||
pngSuite.add('images-file-file', function () {
|
|
||||||
images(fixtures.inputPng)
|
|
||||||
.resize(width, height)
|
|
||||||
.save(fixtures.outputPng);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// sharp
|
// sharp
|
||||||
pngSuite.add('sharp-buffer-file', {
|
pngSuite.add('sharp-buffer-file', {
|
||||||
defer: true,
|
defer: true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user