diff --git a/benchmark.js b/benchmark.js index c5c6e27..77b5113 100644 --- a/benchmark.js +++ b/benchmark.js @@ -25,6 +25,14 @@ suite('chalk', () => { chalkRed('the fox jumps over the lazy dog'); }); + bench('cached: 1 style with 2 arguments', () => { + chalkRed('Error:', 'the fox jumps over the lazy dog'); + }); + + bench('cached: 1 style with 3 arguments', () => { + chalkRed('Error:', 'the fox', 'jumps'); + }); + bench('cached: 2 styles', () => { chalkBlueBgRed('the fox jumps over the lazy dog'); }); diff --git a/source/index.js b/source/index.js index 8bc993d..81073ce 100644 --- a/source/index.js +++ b/source/index.js @@ -150,9 +150,11 @@ const createStyler = (open, close, parent) => { }; const createBuilder = (self, _styler, _isEmpty) => { - // Single argument is hot path, implicit coercion is faster than anything + // Single argument is the hot path, implicit coercion is faster than anything. + // Two arguments is also common (e.g., chalk.red('Error:', message)), + // so we optimize it with direct concatenation instead of join(). // eslint-disable-next-line no-implicit-coercion - const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : ((arguments_.length === 2) ? (arguments_[0] + ' ' + arguments_[1]) : arguments_.join(' '))); // We alter the prototype because we must return a function, but there is // no way to create a function with a different prototype diff --git a/test/chalk.js b/test/chalk.js index 8d58e45..0a1d555 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -69,6 +69,7 @@ test('alias gray to grey', t => { test('support variable number of arguments', t => { t.is(chalk.red('foo', 'bar'), '\u001B[31mfoo bar\u001B[39m'); + t.is(chalk.red('foo', 'bar', 'baz'), '\u001B[31mfoo bar baz\u001B[39m'); }); test('support falsy values', t => {