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; |