Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 94a94a6

Browse files
gurgundayaduh95
authored andcommitted
console: optimize single-string logging
PR-URL: #60422 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 62889d7 commit 94a94a6

File tree

2 files changed

+105
-7
lines changed

2 files changed

+105
-7
lines changed

benchmark/console/log.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict';
2+
3+
// A console throughput benchmark.
4+
// Uses a custom Console with null Writable streams to avoid I/O latency.
5+
6+
const common = require('../common.js');
7+
const { Writable } = require('stream');
8+
const { Console } = require('console');
9+
10+
const bench = common.createBenchmark(main, {
11+
n: [2e6],
12+
variant: ['plain', 'format', 'object', 'group', 'info', 'warn', 'error'],
13+
});
14+
15+
class Null extends Writable {
16+
_write(chunk, enc, cb) { cb(); }
17+
}
18+
19+
function makeConsole() {
20+
const dn = new Null();
21+
return new Console({ stdout: dn, stderr: dn, ignoreErrors: true, colorMode: false });
22+
}
23+
24+
function main({ n, variant }) {
25+
const c = makeConsole();
26+
27+
switch (variant) {
28+
case 'plain': {
29+
bench.start();
30+
for (let i = 0; i < n; i++) c.log('hello world');
31+
bench.end(n);
32+
break;
33+
}
34+
case 'format': {
35+
bench.start();
36+
for (let i = 0; i < n; i++) c.log('%s %d %j', 'a', 42, { x: 1 });
37+
bench.end(n);
38+
break;
39+
}
40+
case 'object': {
41+
const obj = { a: 1, b: 2, c: 3 };
42+
bench.start();
43+
for (let i = 0; i < n; i++) c.log(obj);
44+
bench.end(n);
45+
break;
46+
}
47+
case 'group': {
48+
bench.start();
49+
for (let i = 0; i < n; i++) {
50+
c.group('g');
51+
c.log('x');
52+
c.groupEnd();
53+
}
54+
bench.end(n);
55+
break;
56+
}
57+
case 'info': {
58+
bench.start();
59+
for (let i = 0; i < n; i++) c.info('hello world');
60+
bench.end(n);
61+
break;
62+
}
63+
case 'warn': {
64+
bench.start();
65+
for (let i = 0; i < n; i++) c.warn('hello world');
66+
bench.end(n);
67+
break;
68+
}
69+
case 'error': {
70+
bench.start();
71+
for (let i = 0; i < n; i++) c.error('hello world');
72+
bench.end(n);
73+
break;
74+
}
75+
default:
76+
throw new Error('unknown variant');
77+
}
78+
}

lib/internal/console/constructor.js

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ ObjectDefineProperty(Console, SymbolHasInstance, {
190190
const kColorInspectOptions = { colors: true };
191191
const kNoColorInspectOptions = {};
192192

193-
const internalIndentationMap = new SafeWeakMap();
193+
const kGroupIndentationString = Symbol('kGroupIndentationString');
194194

195195
ObjectDefineProperties(Console.prototype, {
196196
[kBindStreamsEager]: {
@@ -264,6 +264,11 @@ ObjectDefineProperties(Console.prototype, {
264264
...consolePropAttributes,
265265
value: groupIndentation,
266266
},
267+
[kGroupIndentationString]: {
268+
__proto__: null,
269+
...consolePropAttributes,
270+
value: '',
271+
},
267272
[SymbolToStringTag]: {
268273
__proto__: null,
269274
writable: false,
@@ -279,7 +284,7 @@ ObjectDefineProperties(Console.prototype, {
279284
...consolePropAttributes,
280285
value: function(streamSymbol, string) {
281286
const ignoreErrors = this._ignoreErrors;
282-
const groupIndent = internalIndentationMap.get(this) || '';
287+
const groupIndent = this[kGroupIndentationString];
283288

284289
const useStdout = streamSymbol === kUseStdout;
285290
const stream = useStdout ? this._stdout : this._stderr;
@@ -342,6 +347,14 @@ ObjectDefineProperties(Console.prototype, {
342347
__proto__: null,
343348
...consolePropAttributes,
344349
value: function(args) {
350+
if (args.length === 1) {
351+
// Fast path: single string, don't call format.
352+
// Avoids ReflectApply and validation overhead.
353+
const a0 = args[0];
354+
if (typeof a0 === 'string') {
355+
return a0;
356+
}
357+
}
345358
const opts = this[kGetInspectOptions](this._stdout);
346359
ArrayPrototypeUnshift(args, opts);
347360
return ReflectApply(formatWithOptions, null, args);
@@ -351,6 +364,14 @@ ObjectDefineProperties(Console.prototype, {
351364
__proto__: null,
352365
...consolePropAttributes,
353366
value: function(args) {
367+
if (args.length === 1) {
368+
// Fast path: single string, don't call format.
369+
// Avoids ReflectApply and validation overhead.
370+
const a0 = args[0];
371+
if (typeof a0 === 'string') {
372+
return a0;
373+
}
374+
}
354375
const opts = this[kGetInspectOptions](this._stderr);
355376
ArrayPrototypeUnshift(args, opts);
356377
return ReflectApply(formatWithOptions, null, args);
@@ -513,21 +534,20 @@ const consoleMethods = {
513534
ReflectApply(this.log, this, data);
514535
}
515536

516-
let currentIndentation = internalIndentationMap.get(this) || '';
537+
let currentIndentation = this[kGroupIndentationString];
517538
currentIndentation += StringPrototypeRepeat(' ', this[kGroupIndentationWidth]);
518-
519-
internalIndentationMap.set(this, currentIndentation);
539+
this[kGroupIndentationString] = currentIndentation;
520540
},
521541

522542
groupEnd() {
523-
const currentIndentation = internalIndentationMap.get(this) || '';
543+
const currentIndentation = this[kGroupIndentationString];
524544
const newIndentation = StringPrototypeSlice(
525545
currentIndentation,
526546
0,
527547
currentIndentation.length - this[kGroupIndentationWidth],
528548
);
529549

530-
internalIndentationMap.set(this, newIndentation);
550+
this[kGroupIndentationString] = newIndentation;
531551
},
532552

533553
// https://console.spec.whatwg.org/#table

0 commit comments

Comments
 (0)