Skip to content

Commit

Permalink
perf: avoid unnecessary operation for improve performance (#698)
Browse files Browse the repository at this point in the history
  • Loading branch information
cesco69 committed Apr 19, 2024
1 parent 686e6ce commit ed47c66
Showing 1 changed file with 41 additions and 56 deletions.
97 changes: 41 additions & 56 deletions lib/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,29 @@ module.exports = class Serializer {
}

asInteger (i) {
if (typeof i === 'number') {
if (Number.isInteger(i)) {
return '' + i
}
// check if number is Infinity or NaN
// eslint-disable-next-line no-self-compare
if (i === Infinity || i === -Infinity || i !== i) {
throw new Error(`The value "${i}" cannot be converted to an integer.`)
}
return this.parseInteger(i)
} else if (i === null) {
return '0'
if (Number.isInteger(i)) {
return '' + i
} else if (typeof i === 'bigint') {
return i.toString()
} else {
/* eslint no-undef: "off" */
const integer = this.parseInteger(i)
if (Number.isFinite(integer)) {
return '' + integer
} else {
throw new Error(`The value "${i}" cannot be converted to an integer.`)
}
}
/* eslint no-undef: "off" */
const integer = this.parseInteger(i)
// check if number is Infinity or NaN
// eslint-disable-next-line no-self-compare
if (integer === Infinity || integer === -Infinity || integer !== integer) {
throw new Error(`The value "${i}" cannot be converted to an integer.`)
}
return '' + integer
}

asNumber (i) {
const num = Number(i)
// fast cast to number
const num = +i
// check if number is NaN
// eslint-disable-next-line no-self-compare
if (num !== num) {
throw new Error(`The value "${i}" cannot be converted to a number.`)
} else if (!Number.isFinite(num)) {
} else if (num === Infinity || num === -Infinity) {
return 'null'
} else {
return '' + num
Expand Down Expand Up @@ -100,9 +91,34 @@ module.exports = class Serializer {
}

asString (str) {
if (str.length < 42) {
return this.asStringSmall(str)
} else if (str.length < 5000 && STR_ESCAPE.test(str) === false) {
const len = str.length
if (len < 42) {
// magically escape strings for json
// relying on their charCodeAt
// everything below 32 needs JSON.stringify()
// every string that contain surrogate needs JSON.stringify()
// 34 and 92 happens all the time, so we
// have a fast case for them
let result = ''
let last = -1
let point = 255
// eslint-disable-next-line
for (var i = 0; i < len; i++) {
point = str.charCodeAt(i)
if (
point === 0x22 || // '"'
point === 0x5c // '\'
) {
last === -1 && (last = 0)
result += str.slice(last, i) + '\\'
last = i
} else if (point < 32 || (point >= 0xD800 && point <= 0xDFFF)) {
// The current character is non-printable characters or a surrogate.
return JSON.stringify(str)
}
}
return (last === -1 && ('"' + str + '"')) || ('"' + result + str.slice(last) + '"')
} else if (len < 5000 && STR_ESCAPE.test(str) === false) {
// Only use the regular expression for shorter input. The overhead is otherwise too much.
return '"' + str + '"'
} else {
Expand All @@ -114,37 +130,6 @@ module.exports = class Serializer {
return '"' + str + '"'
}

// magically escape strings for json
// relying on their charCodeAt
// everything below 32 needs JSON.stringify()
// every string that contain surrogate needs JSON.stringify()
// 34 and 92 happens all the time, so we
// have a fast case for them
asStringSmall (str) {
const len = str.length
let result = ''
let last = -1
let point = 255

// eslint-disable-next-line
for (var i = 0; i < len; i++) {
point = str.charCodeAt(i)
if (
point === 0x22 || // '"'
point === 0x5c // '\'
) {
last === -1 && (last = 0)
result += str.slice(last, i) + '\\'
last = i
} else if (point < 32 || (point >= 0xD800 && point <= 0xDFFF)) {
// The current character is non-printable characters or a surrogate.
return JSON.stringify(str)
}
}

return (last === -1 && ('"' + str + '"')) || ('"' + result + str.slice(last) + '"')
}

getState () {
return this._options
}
Expand Down

0 comments on commit ed47c66

Please sign in to comment.