lib: use Object.create(null) directly
After V8 5.6, using Object.create(null) directly is now faster than using a constructor for map-like objects. PR-URL: https://github.com/nodejs/node/pull/11930 Refs: https://github.com/emberjs/ember.js/issues/15001 Refs: https://crrev.com/532c16eca071df3ec8eed394dcebb932ef584ee6 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
14a91957f8
commit
cfc8422a68
@ -31,7 +31,6 @@ const common = require('_http_common');
|
|||||||
const checkIsHttpToken = common._checkIsHttpToken;
|
const checkIsHttpToken = common._checkIsHttpToken;
|
||||||
const checkInvalidHeaderChar = common._checkInvalidHeaderChar;
|
const checkInvalidHeaderChar = common._checkInvalidHeaderChar;
|
||||||
const outHeadersKey = require('internal/http').outHeadersKey;
|
const outHeadersKey = require('internal/http').outHeadersKey;
|
||||||
const StorageObject = require('internal/querystring').StorageObject;
|
|
||||||
|
|
||||||
const CRLF = common.CRLF;
|
const CRLF = common.CRLF;
|
||||||
const debug = common.debug;
|
const debug = common.debug;
|
||||||
@ -143,7 +142,7 @@ Object.defineProperty(OutgoingMessage.prototype, '_headerNames', {
|
|||||||
get: function() {
|
get: function() {
|
||||||
const headers = this[outHeadersKey];
|
const headers = this[outHeadersKey];
|
||||||
if (headers) {
|
if (headers) {
|
||||||
const out = new StorageObject();
|
const out = Object.create(null);
|
||||||
const keys = Object.keys(headers);
|
const keys = Object.keys(headers);
|
||||||
for (var i = 0; i < keys.length; ++i) {
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
const key = keys[i];
|
const key = keys[i];
|
||||||
@ -552,7 +551,7 @@ OutgoingMessage.prototype.getHeaderNames = function getHeaderNames() {
|
|||||||
// Returns a shallow copy of the current outgoing headers.
|
// Returns a shallow copy of the current outgoing headers.
|
||||||
OutgoingMessage.prototype.getHeaders = function getHeaders() {
|
OutgoingMessage.prototype.getHeaders = function getHeaders() {
|
||||||
const headers = this[outHeadersKey];
|
const headers = this[outHeadersKey];
|
||||||
const ret = new StorageObject();
|
const ret = Object.create(null);
|
||||||
if (headers) {
|
if (headers) {
|
||||||
const keys = Object.keys(headers);
|
const keys = Object.keys(headers);
|
||||||
for (var i = 0; i < keys.length; ++i) {
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
@ -23,12 +23,6 @@
|
|||||||
|
|
||||||
var domain;
|
var domain;
|
||||||
|
|
||||||
// This constructor is used to store event handlers. Instantiating this is
|
|
||||||
// faster than explicitly calling `Object.create(null)` to get a "clean" empty
|
|
||||||
// object (tested with v8 v4.9).
|
|
||||||
function EventHandlers() {}
|
|
||||||
EventHandlers.prototype = Object.create(null);
|
|
||||||
|
|
||||||
function EventEmitter() {
|
function EventEmitter() {
|
||||||
EventEmitter.init.call(this);
|
EventEmitter.init.call(this);
|
||||||
}
|
}
|
||||||
@ -75,7 +69,7 @@ EventEmitter.init = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
|
if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
|
||||||
this._events = new EventHandlers();
|
this._events = Object.create(null);
|
||||||
this._eventsCount = 0;
|
this._eventsCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +239,7 @@ function _addListener(target, type, listener, prepend) {
|
|||||||
|
|
||||||
events = target._events;
|
events = target._events;
|
||||||
if (!events) {
|
if (!events) {
|
||||||
events = target._events = new EventHandlers();
|
events = target._events = Object.create(null);
|
||||||
target._eventsCount = 0;
|
target._eventsCount = 0;
|
||||||
} else {
|
} else {
|
||||||
// To avoid recursion in the case that type === "newListener"! Before
|
// To avoid recursion in the case that type === "newListener"! Before
|
||||||
@ -360,7 +354,7 @@ EventEmitter.prototype.removeListener =
|
|||||||
|
|
||||||
if (list === listener || list.listener === listener) {
|
if (list === listener || list.listener === listener) {
|
||||||
if (--this._eventsCount === 0)
|
if (--this._eventsCount === 0)
|
||||||
this._events = new EventHandlers();
|
this._events = Object.create(null);
|
||||||
else {
|
else {
|
||||||
delete events[type];
|
delete events[type];
|
||||||
if (events.removeListener)
|
if (events.removeListener)
|
||||||
@ -383,7 +377,7 @@ EventEmitter.prototype.removeListener =
|
|||||||
if (list.length === 1) {
|
if (list.length === 1) {
|
||||||
list[0] = undefined;
|
list[0] = undefined;
|
||||||
if (--this._eventsCount === 0) {
|
if (--this._eventsCount === 0) {
|
||||||
this._events = new EventHandlers();
|
this._events = Object.create(null);
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
delete events[type];
|
delete events[type];
|
||||||
@ -412,11 +406,11 @@ EventEmitter.prototype.removeAllListeners =
|
|||||||
// not listening for removeListener, no need to emit
|
// not listening for removeListener, no need to emit
|
||||||
if (!events.removeListener) {
|
if (!events.removeListener) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
this._events = new EventHandlers();
|
this._events = Object.create(null);
|
||||||
this._eventsCount = 0;
|
this._eventsCount = 0;
|
||||||
} else if (events[type]) {
|
} else if (events[type]) {
|
||||||
if (--this._eventsCount === 0)
|
if (--this._eventsCount === 0)
|
||||||
this._events = new EventHandlers();
|
this._events = Object.create(null);
|
||||||
else
|
else
|
||||||
delete events[type];
|
delete events[type];
|
||||||
}
|
}
|
||||||
@ -432,7 +426,7 @@ EventEmitter.prototype.removeAllListeners =
|
|||||||
this.removeAllListeners(key);
|
this.removeAllListeners(key);
|
||||||
}
|
}
|
||||||
this.removeAllListeners('removeListener');
|
this.removeAllListeners('removeListener');
|
||||||
this._events = new EventHandlers();
|
this._events = Object.create(null);
|
||||||
this._eventsCount = 0;
|
this._eventsCount = 0;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
11
lib/fs.js
11
lib/fs.js
@ -43,7 +43,6 @@ const internalUtil = require('internal/util');
|
|||||||
const assertEncoding = internalFS.assertEncoding;
|
const assertEncoding = internalFS.assertEncoding;
|
||||||
const stringToFlags = internalFS.stringToFlags;
|
const stringToFlags = internalFS.stringToFlags;
|
||||||
const getPathFromURL = internalURL.getPathFromURL;
|
const getPathFromURL = internalURL.getPathFromURL;
|
||||||
const { StorageObject } = require('internal/querystring');
|
|
||||||
|
|
||||||
Object.defineProperty(exports, 'constants', {
|
Object.defineProperty(exports, 'constants', {
|
||||||
configurable: false,
|
configurable: false,
|
||||||
@ -1560,7 +1559,7 @@ if (isWindows) {
|
|||||||
nextPart = function nextPart(p, i) { return p.indexOf('/', i); };
|
nextPart = function nextPart(p, i) { return p.indexOf('/', i); };
|
||||||
}
|
}
|
||||||
|
|
||||||
const emptyObj = new StorageObject();
|
const emptyObj = Object.create(null);
|
||||||
fs.realpathSync = function realpathSync(p, options) {
|
fs.realpathSync = function realpathSync(p, options) {
|
||||||
if (!options)
|
if (!options)
|
||||||
options = emptyObj;
|
options = emptyObj;
|
||||||
@ -1580,8 +1579,8 @@ fs.realpathSync = function realpathSync(p, options) {
|
|||||||
return maybeCachedResult;
|
return maybeCachedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
const seenLinks = new StorageObject();
|
const seenLinks = Object.create(null);
|
||||||
const knownHard = new StorageObject();
|
const knownHard = Object.create(null);
|
||||||
const original = p;
|
const original = p;
|
||||||
|
|
||||||
// current character position in p
|
// current character position in p
|
||||||
@ -1700,8 +1699,8 @@ fs.realpath = function realpath(p, options, callback) {
|
|||||||
return;
|
return;
|
||||||
p = pathModule.resolve(p);
|
p = pathModule.resolve(p);
|
||||||
|
|
||||||
const seenLinks = new StorageObject();
|
const seenLinks = Object.create(null);
|
||||||
const knownHard = new StorageObject();
|
const knownHard = Object.create(null);
|
||||||
|
|
||||||
// current character position in p
|
// current character position in p
|
||||||
var pos;
|
var pos;
|
||||||
|
@ -23,13 +23,7 @@ const isHexTable = [
|
|||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // ... 256
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // ... 256
|
||||||
];
|
];
|
||||||
|
|
||||||
// Instantiating this is faster than explicitly calling `Object.create(null)`
|
|
||||||
// to get a "clean" empty object (tested with v8 v4.9).
|
|
||||||
function StorageObject() {}
|
|
||||||
StorageObject.prototype = Object.create(null);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
hexTable,
|
hexTable,
|
||||||
isHexTable,
|
isHexTable
|
||||||
StorageObject
|
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
const { Buffer } = require('buffer');
|
const { Buffer } = require('buffer');
|
||||||
const {
|
const {
|
||||||
StorageObject,
|
|
||||||
hexTable,
|
hexTable,
|
||||||
isHexTable
|
isHexTable
|
||||||
} = require('internal/querystring');
|
} = require('internal/querystring');
|
||||||
@ -281,7 +280,7 @@ const defEqCodes = [61]; // =
|
|||||||
|
|
||||||
// Parse a key/val string.
|
// Parse a key/val string.
|
||||||
function parse(qs, sep, eq, options) {
|
function parse(qs, sep, eq, options) {
|
||||||
const obj = new StorageObject();
|
const obj = Object.create(null);
|
||||||
|
|
||||||
if (typeof qs !== 'string' || qs.length === 0) {
|
if (typeof qs !== 'string' || qs.length === 0) {
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
const { toASCII } = process.binding('config').hasIntl ?
|
const { toASCII } = process.binding('config').hasIntl ?
|
||||||
process.binding('icu') : require('punycode');
|
process.binding('icu') : require('punycode');
|
||||||
const { StorageObject, hexTable } = require('internal/querystring');
|
const { hexTable } = require('internal/querystring');
|
||||||
const internalUrl = require('internal/url');
|
const internalUrl = require('internal/url');
|
||||||
exports.parse = urlParse;
|
exports.parse = urlParse;
|
||||||
exports.resolve = urlResolve;
|
exports.resolve = urlResolve;
|
||||||
@ -197,7 +197,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
|
|||||||
}
|
}
|
||||||
} else if (parseQueryString) {
|
} else if (parseQueryString) {
|
||||||
this.search = '';
|
this.search = '';
|
||||||
this.query = new StorageObject();
|
this.query = Object.create(null);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -390,7 +390,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
|
|||||||
} else if (parseQueryString) {
|
} else if (parseQueryString) {
|
||||||
// no query string, but parseQueryString still requested
|
// no query string, but parseQueryString still requested
|
||||||
this.search = '';
|
this.search = '';
|
||||||
this.query = new StorageObject();
|
this.query = Object.create(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstIdx = (questionIdx !== -1 &&
|
var firstIdx = (questionIdx !== -1 &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user