From e16124979de1db9af6e73db530623b3e7648df15 Mon Sep 17 00:00:00 2001 From: sapics Date: Sun, 5 Jul 2020 09:47:39 +0900 Subject: [PATCH] querystring: reduce memory usage by Int8Array PR-URL: https://github.com/nodejs/node/pull/34179 Reviewed-By: Anna Henningsen Reviewed-By: Denys Otrishko Reviewed-By: Antoine du Hamel --- lib/internal/querystring.js | 5 +++-- lib/internal/url.js | 5 +++-- lib/querystring.js | 9 +++++---- lib/url.js | 5 +++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/internal/querystring.js b/lib/internal/querystring.js index ee589e1984294d..5306c7f82bb14a 100644 --- a/lib/internal/querystring.js +++ b/lib/internal/querystring.js @@ -2,6 +2,7 @@ const { Array, + Int8Array, } = primordials; const { ERR_INVALID_URI } = require('internal/errors').codes; @@ -10,7 +11,7 @@ const hexTable = new Array(256); for (let i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); -const isHexTable = [ +const isHexTable = new Int8Array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32 - 47 @@ -27,7 +28,7 @@ const isHexTable = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // ... 256 -]; +]); function encodeStr(str, noEscapeTable, hexTable) { const len = str.length; diff --git a/lib/internal/url.js b/lib/internal/url.js index 0a5be32e467715..22dc145b85e0c7 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -2,6 +2,7 @@ const { Array, + Int8Array, Number, ObjectCreate, ObjectDefineProperties, @@ -817,7 +818,7 @@ function parseParams(qs) { // Adapted from querystring's implementation. // Ref: https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer -const noEscape = [ +const noEscape = new Int8Array([ /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F */ @@ -829,7 +830,7 @@ const noEscape = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 0x50 - 0x5F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 // 0x70 - 0x7F -]; +]); // Special version of hexTable that uses `+` for U+0020 SPACE. const paramHexTable = hexTable.slice(); diff --git a/lib/querystring.js b/lib/querystring.js index 04a21e8d07f24f..df954cfbd85211 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -26,6 +26,7 @@ const { Array, ArrayIsArray, + Int8Array, MathAbs, ObjectCreate, ObjectKeys, @@ -53,7 +54,7 @@ const QueryString = module.exports = { decode: parse }; -const unhexTable = [ +const unhexTable = new Int8Array([ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32 - 47 @@ -70,7 +71,7 @@ const unhexTable = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // ... 255 -]; +]); // A safe fast alternative to decodeURIComponent function unescapeBuffer(s, decodeSpaces) { const out = Buffer.allocUnsafe(s.length); @@ -130,7 +131,7 @@ function qsUnescape(s, decodeSpaces) { // digits // alpha (uppercase) // alpha (lowercase) -const noEscape = [ +const noEscape = new Int8Array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, // 32 - 47 @@ -139,7 +140,7 @@ const noEscape = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 80 - 95 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 // 112 - 127 -]; +]); // QueryString.escape() replaces encodeURIComponent() // https://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3.4 function qsEscape(str) { diff --git a/lib/url.js b/lib/url.js index 735390dfd2e59b..cc36216f9eb916 100644 --- a/lib/url.js +++ b/lib/url.js @@ -22,6 +22,7 @@ 'use strict'; const { + Int8Array, ObjectCreate, ObjectKeys, SafeSet, @@ -561,7 +562,7 @@ function urlFormat(urlObject, options) { // digits // alpha (uppercase) // alpha (lowercase) -const noEscapeAuth = [ +const noEscapeAuth = new Int8Array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, // 0x20 - 0x2F @@ -570,7 +571,7 @@ const noEscapeAuth = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 0x50 - 0x5F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 // 0x70 - 0x7F -]; +]); Url.prototype.format = function format() { let auth = this.auth || '';