diff --git a/README.md b/README.md index 1661f7ea..d1f6bca6 100755 --- a/README.md +++ b/README.md @@ -365,6 +365,18 @@ sharp.cache(200); // { current: 75, high: 99, memory: 200, items: 500 } sharp.cache(50, 200); // { current: 49, high: 99, memory: 50, items: 200} ``` +#### sharp.concurrency([threads]) + +`threads`, if provided, is the Number of threads _libvips'_ should create for image processing. The default value is the number of CPU cores. A value of `0` will reset to this default. + +This method always returns the current concurrency. + +```javascript +var threads = sharp.concurrency(); // 4 +sharp.concurrency(2); // 2 +sharp.concurrency(0); // 4 +``` + #### sharp.counters() Provides access to internal task counters. diff --git a/index.js b/index.js index df5fba9d..5636aeb1 100755 --- a/index.js +++ b/index.js @@ -430,6 +430,16 @@ module.exports.cache = function(memory, items) { return sharp.cache(memory, items); }; +/* + Get and set size of thread pool +*/ +module.exports.concurrency = function(concurrency) { + if (Number.isNaN(concurrency)) { + concurrency = null; + } + return sharp.concurrency(concurrency); +}; + /* Get internal counters */ diff --git a/src/sharp.cc b/src/sharp.cc index 8c2fd102..d955c2d3 100755 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -775,6 +775,20 @@ NAN_METHOD(cache) { NanReturnValue(cache); } +/* + Get and set size of thread pool +*/ +NAN_METHOD(concurrency) { + NanScope(); + + // Set concurrency + if (args[0]->IsInt32()) { + vips_concurrency_set(args[0]->Int32Value()); + } + // Get concurrency + NanReturnValue(NanNew(vips_concurrency_get())); +} + /* Get internal counters (queued tasks, processing tasks) */ @@ -807,6 +821,7 @@ extern "C" void init(Handle target) { NODE_SET_METHOD(target, "metadata", metadata); NODE_SET_METHOD(target, "resize", resize); NODE_SET_METHOD(target, "cache", cache); + NODE_SET_METHOD(target, "concurrency", concurrency); NODE_SET_METHOD(target, "counters", counters); } diff --git a/tests/parallel.js b/tests/parallel.js index e72de08e..1377833f 100755 --- a/tests/parallel.js +++ b/tests/parallel.js @@ -1,37 +1,39 @@ -var sharp = require("../index"); -var fs = require("fs"); -var path = require("path"); -var assert = require("assert"); -var async = require("async"); - -var inputJpg = path.join(__dirname, "fixtures/2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/ -var width = 720; -var height = 480; - -var timer = setInterval(function() { - console.dir(sharp.cache()); -}, 100); - -async.mapSeries([1, 1, 2, 4, 8, 16, 32, 64, 128], function(parallelism, next) { - var start = new Date().getTime(); - async.times(parallelism, - function(id, callback) { - sharp(inputJpg).resize(width, height).toBuffer(function(err, buffer) { - buffer = null; - callback(err, new Date().getTime() - start); - }); - }, - function(err, ids) { - assert(!err); - assert(ids.length === parallelism); - var mean = ids.reduce(function(a, b) { - return a + b; - }) / ids.length; - console.log(parallelism + " parallel calls: fastest=" + ids[0] + "ms slowest=" + ids[ids.length - 1] + "ms mean=" + mean + "ms"); - next(); - } - ); -}, function() { - clearInterval(timer); - console.dir(sharp.cache()); -}); +var sharp = require("../index"); +var fs = require("fs"); +var path = require("path"); +var assert = require("assert"); +var async = require("async"); + +var inputJpg = path.join(__dirname, "fixtures/2569067123_aca715a2ee_o.jpg"); // http://www.flickr.com/photos/grizdave/2569067123/ +var width = 720; +var height = 480; + +sharp.concurrency(1); + +var timer = setInterval(function() { + console.dir(sharp.counters()); +}, 100); + +async.mapSeries([1, 1, 2, 4, 8, 16, 32, 64, 128], function(parallelism, next) { + var start = new Date().getTime(); + async.times(parallelism, + function(id, callback) { + sharp(inputJpg).resize(width, height).toBuffer(function(err, buffer) { + buffer = null; + callback(err, new Date().getTime() - start); + }); + }, + function(err, ids) { + assert(!err); + assert(ids.length === parallelism); + var mean = ids.reduce(function(a, b) { + return a + b; + }) / ids.length; + console.log(parallelism + " parallel calls: fastest=" + ids[0] + "ms slowest=" + ids[ids.length - 1] + "ms mean=" + mean + "ms"); + next(); + } + ); +}, function() { + clearInterval(timer); + console.dir(sharp.counters()); +}); diff --git a/tests/unit.js b/tests/unit.js index 525b26f6..85bb858e 100755 --- a/tests/unit.js +++ b/tests/unit.js @@ -28,6 +28,13 @@ var inputGif = path.join(fixturesPath, "Crash_test.gif"); // http://upload.wikim sharp.cache(0); // Disable sharp.cache(50, 500); // 50MB, 500 items +// Ensure concurrency can be set +var defaultConcurrency = sharp.concurrency(); +sharp.concurrency(16); +assert.strictEqual(16, sharp.concurrency()); +sharp.concurrency(0); +assert.strictEqual(defaultConcurrency, sharp.concurrency()); + async.series([ // Resize with exact crop function(done) {