Skip to content

Commit ed47c66

Browse files
authored
perf: avoid unnecessary operation for improve performance (#698)
1 parent 686e6ce commit ed47c66

File tree

1 file changed

+41
-56
lines changed

1 file changed

+41
-56
lines changed

lib/serializer.js

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,29 @@ module.exports = class Serializer {
2424
}
2525

2626
asInteger (i) {
27-
if (typeof i === 'number') {
28-
if (Number.isInteger(i)) {
29-
return '' + i
30-
}
31-
// check if number is Infinity or NaN
32-
// eslint-disable-next-line no-self-compare
33-
if (i === Infinity || i === -Infinity || i !== i) {
34-
throw new Error(`The value "${i}" cannot be converted to an integer.`)
35-
}
36-
return this.parseInteger(i)
37-
} else if (i === null) {
38-
return '0'
27+
if (Number.isInteger(i)) {
28+
return '' + i
3929
} else if (typeof i === 'bigint') {
4030
return i.toString()
41-
} else {
42-
/* eslint no-undef: "off" */
43-
const integer = this.parseInteger(i)
44-
if (Number.isFinite(integer)) {
45-
return '' + integer
46-
} else {
47-
throw new Error(`The value "${i}" cannot be converted to an integer.`)
48-
}
4931
}
32+
/* eslint no-undef: "off" */
33+
const integer = this.parseInteger(i)
34+
// check if number is Infinity or NaN
35+
// eslint-disable-next-line no-self-compare
36+
if (integer === Infinity || integer === -Infinity || integer !== integer) {
37+
throw new Error(`The value "${i}" cannot be converted to an integer.`)
38+
}
39+
return '' + integer
5040
}
5141

5242
asNumber (i) {
53-
const num = Number(i)
43+
// fast cast to number
44+
const num = +i
5445
// check if number is NaN
5546
// eslint-disable-next-line no-self-compare
5647
if (num !== num) {
5748
throw new Error(`The value "${i}" cannot be converted to a number.`)
58-
} else if (!Number.isFinite(num)) {
49+
} else if (num === Infinity || num === -Infinity) {
5950
return 'null'
6051
} else {
6152
return '' + num
@@ -100,9 +91,34 @@ module.exports = class Serializer {
10091
}
10192

10293
asString (str) {
103-
if (str.length < 42) {
104-
return this.asStringSmall(str)
105-
} else if (str.length < 5000 && STR_ESCAPE.test(str) === false) {
94+
const len = str.length
95+
if (len < 42) {
96+
// magically escape strings for json
97+
// relying on their charCodeAt
98+
// everything below 32 needs JSON.stringify()
99+
// every string that contain surrogate needs JSON.stringify()
100+
// 34 and 92 happens all the time, so we
101+
// have a fast case for them
102+
let result = ''
103+
let last = -1
104+
let point = 255
105+
// eslint-disable-next-line
106+
for (var i = 0; i < len; i++) {
107+
point = str.charCodeAt(i)
108+
if (
109+
point === 0x22 || // '"'
110+
point === 0x5c // '\'
111+
) {
112+
last === -1 && (last = 0)
113+
result += str.slice(last, i) + '\\'
114+
last = i
115+
} else if (point < 32 || (point >= 0xD800 && point <= 0xDFFF)) {
116+
// The current character is non-printable characters or a surrogate.
117+
return JSON.stringify(str)
118+
}
119+
}
120+
return (last === -1 && ('"' + str + '"')) || ('"' + result + str.slice(last) + '"')
121+
} else if (len < 5000 && STR_ESCAPE.test(str) === false) {
106122
// Only use the regular expression for shorter input. The overhead is otherwise too much.
107123
return '"' + str + '"'
108124
} else {
@@ -114,37 +130,6 @@ module.exports = class Serializer {
114130
return '"' + str + '"'
115131
}
116132

117-
// magically escape strings for json
118-
// relying on their charCodeAt
119-
// everything below 32 needs JSON.stringify()
120-
// every string that contain surrogate needs JSON.stringify()
121-
// 34 and 92 happens all the time, so we
122-
// have a fast case for them
123-
asStringSmall (str) {
124-
const len = str.length
125-
let result = ''
126-
let last = -1
127-
let point = 255
128-
129-
// eslint-disable-next-line
130-
for (var i = 0; i < len; i++) {
131-
point = str.charCodeAt(i)
132-
if (
133-
point === 0x22 || // '"'
134-
point === 0x5c // '\'
135-
) {
136-
last === -1 && (last = 0)
137-
result += str.slice(last, i) + '\\'
138-
last = i
139-
} else if (point < 32 || (point >= 0xD800 && point <= 0xDFFF)) {
140-
// The current character is non-printable characters or a surrogate.
141-
return JSON.stringify(str)
142-
}
143-
}
144-
145-
return (last === -1 && ('"' + str + '"')) || ('"' + result + str.slice(last) + '"')
146-
}
147-
148133
getState () {
149134
return this._options
150135
}

0 commit comments

Comments
 (0)