lib: faster FreeList · nodejs/node@47f5cc1 (original) (raw)

7 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -9,7 +9,9 @@ const bench = common.createBenchmark(main, {
9 9 });
10 10
11 11 function main({ n }) {
12 -const { FreeList } = require('internal/freelist');
12 +let FreeList = require('internal/freelist');
13 +if (FreeList.FreeList)
14 +FreeList = FreeList.FreeList;
13 15 const poolSize = 1000;
14 16 const list = new FreeList('test', poolSize, Object);
15 17 var j;
Original file line number Diff line number Diff line change
@@ -46,7 +46,6 @@ const {
46 46 ERR_UNESCAPED_CHARACTERS
47 47 } = require('internal/errors').codes;
48 48 const { getTimerDuration } = require('internal/timers');
49 -const is_reused_symbol = require('internal/freelist').symbols.is_reused_symbol;
50 49 const {
51 50 DTRACE_HTTP_CLIENT_REQUEST,
52 51 DTRACE_HTTP_CLIENT_RESPONSE
@@ -631,10 +630,11 @@ function emitFreeNT(socket) {
631 630 }
632 631
633 632 function tickOnSocket(req, socket) {
633 +const isParserReused = parsers.hasItems();
634 634 const parser = parsers.alloc();
635 635 req.socket = socket;
636 636 req.connection = socket;
637 -parser.reinitialize(HTTPParser.RESPONSE, parser[is_reused_symbol]);
637 +parser.reinitialize(HTTPParser.RESPONSE, isParserReused);
638 638 parser.socket = socket;
639 639 parser.outgoing = req;
640 640 req.parser = parser;
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ const { methods, HTTPParser } =
29 29 getOptionValue('--http-parser') === 'legacy' ?
30 30 internalBinding('http_parser') : internalBinding('http_parser_llhttp');
31 31
32 -const { FreeList } = require('internal/freelist');
32 +const FreeList = require('internal/freelist');
33 33 const { ondrain } = require('internal/http');
34 34 const incoming = require('_http_incoming');
35 35 const {
Original file line number Diff line number Diff line change
@@ -41,7 +41,6 @@ const {
41 41 defaultTriggerAsyncIdScope,
42 42 getOrSetAsyncId
43 43 } = require('internal/async_hooks');
44 -const is_reused_symbol = require('internal/freelist').symbols.is_reused_symbol;
45 44 const { IncomingMessage } = require('_http_incoming');
46 45 const {
47 46 ERR_HTTP_HEADERS_SENT,
@@ -348,8 +347,9 @@ function connectionListenerInternal(server, socket) {
348 347 socket.setTimeout(server.timeout);
349 348 socket.on('timeout', socketOnTimeout);
350 349
350 +const isParserReused = parsers.hasItems();
351 351 const parser = parsers.alloc();
352 -parser.reinitialize(HTTPParser.REQUEST, parser[is_reused_symbol]);
352 +parser.reinitialize(HTTPParser.REQUEST, isParserReused);
353 353 parser.socket = socket;
354 354
355 355 // We are starting to wait for our headers.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
1 1 'use strict';
2 2
3 -const is_reused_symbol = Symbol('isReused');
3 +const { Reflect } = primordials;
4 4
5 5 class FreeList {
6 6 constructor(name, max, ctor) {
@@ -10,16 +10,14 @@ class FreeList {
10 10 this.list = [];
11 11 }
12 12
13 +hasItems() {
14 +return this.list.length > 0;
15 +}
16 +
13 17 alloc() {
14 -let item;
15 -if (this.list.length > 0) {
16 -item = this.list.pop();
17 -item[is_reused_symbol] = true;
18 -} else {
19 -item = this.ctor.apply(this, arguments);
20 -item[is_reused_symbol] = false;
21 -}
22 -return item;
18 +return this.list.length > 0 ?
19 +this.list.pop() :
20 +Reflect.apply(this.ctor, this, arguments);
23 21 }
24 22
25 23 free(obj) {
@@ -31,9 +29,4 @@ class FreeList {
31 29 }
32 30 }
33 31
34 -module.exports = {
35 - FreeList,
36 -symbols: {
37 - is_reused_symbol
38 -}
39 -};
32 +module.exports = FreeList;
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
4 4
5 5 require('../common');
6 6 const assert = require('assert');
7 -const { FreeList } = require('internal/freelist');
7 +const FreeList = require('internal/freelist');
8 8
9 9 assert.strictEqual(typeof FreeList, 'function');
10 10
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
6 6 const common = require('../common');
7 7 const assert = require('assert');
8 8 const httpCommon = require('_http_common');
9 -const is_reused_symbol = require('internal/freelist').symbols.is_reused_symbol;
10 9 const { HTTPParser } = require('_http_common');
11 10 const net = require('net');
12 11
@@ -25,14 +24,15 @@ function execAndClose() {
25 24 process.stdout.write('.');
26 25
27 26 const parser = parsers.pop();
28 -parser.reinitialize(HTTPParser.RESPONSE, parser[is_reused_symbol]);
27 +parser.reinitialize(HTTPParser.RESPONSE, !!parser.reused);
29 28
30 29 const socket = net.connect(common.PORT);
31 30 socket.on('error', (e) => {
32 31 // If SmartOS and ECONNREFUSED, then retry. See
33 32 // https://github.com/nodejs/node/issues/2663.
34 33 if (common.isSunOS && e.code === 'ECONNREFUSED') {
35 34 parsers.push(parser);
35 +parser.reused = true;
36 36 socket.destroy();
37 37 setImmediate(execAndClose);
38 38 return;