fast-json-stringify 3.0.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/benchmark.yml +9 -4
- package/.github/workflows/ci.yml +3 -33
- package/README.md +65 -11
- package/benchmark/bench-cmp-branch.js +114 -0
- package/{bench.js → benchmark/bench-cmp-lib.js} +70 -8
- package/benchmark/bench-thread.js +21 -0
- package/benchmark/bench.js +251 -0
- package/example.js +1 -4
- package/index.d.ts +4 -0
- package/index.js +540 -585
- package/package.json +13 -6
- package/test/additionalProperties.test.js +23 -19
- package/test/allof.test.js +56 -0
- package/test/anyof.test.js +88 -9
- package/test/array.test.js +126 -24
- package/test/basic.test.js +8 -8
- package/test/date.test.js +62 -35
- package/test/debug-mode.test.js +1 -1
- package/test/if-then-else.test.js +2 -2
- package/test/nestedObjects.test.js +31 -0
- package/test/nullable.test.js +343 -15
- package/test/oneof.test.js +9 -22
- package/test/patternProperties.test.js +17 -6
- package/test/recursion.test.js +65 -0
- package/test/required.test.js +1 -1
- package/test/sanitize3.test.js +9 -11
- package/test/typesArray.test.js +40 -3
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const { Worker } = require('worker_threads')
|
|
5
|
+
|
|
6
|
+
const BENCH_THREAD_PATH = path.join(__dirname, 'bench-thread.js')
|
|
7
|
+
|
|
8
|
+
const LONG_STRING_LENGTH = 1e4
|
|
9
|
+
const SHORT_ARRAY_SIZE = 1e3
|
|
10
|
+
|
|
11
|
+
const shortArrayOfNumbers = new Array(SHORT_ARRAY_SIZE)
|
|
12
|
+
const shortArrayOfIntegers = new Array(SHORT_ARRAY_SIZE)
|
|
13
|
+
const shortArrayOfShortStrings = new Array(SHORT_ARRAY_SIZE)
|
|
14
|
+
const shortArrayOfLongStrings = new Array(SHORT_ARRAY_SIZE)
|
|
15
|
+
const shortArrayOfMultiObject = new Array(SHORT_ARRAY_SIZE)
|
|
16
|
+
|
|
17
|
+
function getRandomInt (max) {
|
|
18
|
+
return Math.floor(Math.random() * max)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let longString = ''
|
|
22
|
+
for (let i = 0; i < LONG_STRING_LENGTH; i++) {
|
|
23
|
+
longString += i
|
|
24
|
+
if (i % 100 === 0) {
|
|
25
|
+
longString += '"'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < SHORT_ARRAY_SIZE; i++) {
|
|
30
|
+
shortArrayOfNumbers[i] = getRandomInt(1000)
|
|
31
|
+
shortArrayOfIntegers[i] = getRandomInt(1000)
|
|
32
|
+
shortArrayOfShortStrings[i] = 'hello world'
|
|
33
|
+
shortArrayOfLongStrings[i] = longString
|
|
34
|
+
shortArrayOfMultiObject[i] = { s: 'hello world', n: 42, b: true }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const benchmarks = [
|
|
38
|
+
{
|
|
39
|
+
name: 'short string',
|
|
40
|
+
schema: {
|
|
41
|
+
type: 'string'
|
|
42
|
+
},
|
|
43
|
+
input: 'hello world'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'long string',
|
|
47
|
+
schema: {
|
|
48
|
+
type: 'string'
|
|
49
|
+
},
|
|
50
|
+
input: longString
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'number',
|
|
54
|
+
schema: {
|
|
55
|
+
type: 'number'
|
|
56
|
+
},
|
|
57
|
+
input: 42
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'integer',
|
|
61
|
+
schema: {
|
|
62
|
+
type: 'integer'
|
|
63
|
+
},
|
|
64
|
+
input: 42
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'formatted date-time',
|
|
68
|
+
schema: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
format: 'date-time'
|
|
71
|
+
},
|
|
72
|
+
input: new Date()
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'formatted date',
|
|
76
|
+
schema: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
format: 'date'
|
|
79
|
+
},
|
|
80
|
+
input: new Date()
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'formatted time',
|
|
84
|
+
schema: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
format: 'time'
|
|
87
|
+
},
|
|
88
|
+
input: new Date()
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'short array of numbers',
|
|
92
|
+
schema: {
|
|
93
|
+
type: 'array',
|
|
94
|
+
items: { type: 'number' }
|
|
95
|
+
},
|
|
96
|
+
input: shortArrayOfNumbers
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'short array of integers',
|
|
100
|
+
schema: {
|
|
101
|
+
type: 'array',
|
|
102
|
+
items: { type: 'integer' }
|
|
103
|
+
},
|
|
104
|
+
input: shortArrayOfIntegers
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'short array of short strings',
|
|
108
|
+
schema: {
|
|
109
|
+
type: 'array',
|
|
110
|
+
items: { type: 'string' }
|
|
111
|
+
},
|
|
112
|
+
input: shortArrayOfShortStrings
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'short array of long strings',
|
|
116
|
+
schema: {
|
|
117
|
+
type: 'array',
|
|
118
|
+
items: { type: 'string' }
|
|
119
|
+
},
|
|
120
|
+
input: shortArrayOfShortStrings
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'short array of objects with properties of different types',
|
|
124
|
+
schema: {
|
|
125
|
+
type: 'array',
|
|
126
|
+
items: {
|
|
127
|
+
type: 'object',
|
|
128
|
+
properties: {
|
|
129
|
+
s: { type: 'string' },
|
|
130
|
+
n: { type: 'number' },
|
|
131
|
+
b: { type: 'boolean' }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
input: shortArrayOfMultiObject
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'object with number property',
|
|
139
|
+
schema: {
|
|
140
|
+
type: 'object',
|
|
141
|
+
properties: {
|
|
142
|
+
a: { type: 'number' }
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
input: { a: 42 }
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'object with integer property',
|
|
149
|
+
schema: {
|
|
150
|
+
type: 'object',
|
|
151
|
+
properties: {
|
|
152
|
+
a: { type: 'integer' }
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
input: { a: 42 }
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'object with short string property',
|
|
159
|
+
schema: {
|
|
160
|
+
type: 'object',
|
|
161
|
+
properties: {
|
|
162
|
+
a: { type: 'string' }
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
input: { a: 'hello world' }
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'object with long string property',
|
|
169
|
+
schema: {
|
|
170
|
+
type: 'object',
|
|
171
|
+
properties: {
|
|
172
|
+
a: { type: 'string' }
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
input: { a: longString }
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'object with properties of different types',
|
|
179
|
+
schema: {
|
|
180
|
+
type: 'object',
|
|
181
|
+
properties: {
|
|
182
|
+
s1: { type: 'string' },
|
|
183
|
+
n1: { type: 'number' },
|
|
184
|
+
b1: { type: 'boolean' },
|
|
185
|
+
s2: { type: 'string' },
|
|
186
|
+
n2: { type: 'number' },
|
|
187
|
+
b2: { type: 'boolean' },
|
|
188
|
+
s3: { type: 'string' },
|
|
189
|
+
n3: { type: 'number' },
|
|
190
|
+
b3: { type: 'boolean' },
|
|
191
|
+
s4: { type: 'string' },
|
|
192
|
+
n4: { type: 'number' },
|
|
193
|
+
b4: { type: 'boolean' },
|
|
194
|
+
s5: { type: 'string' },
|
|
195
|
+
n5: { type: 'number' },
|
|
196
|
+
b5: { type: 'boolean' }
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
input: {
|
|
200
|
+
s1: 'hello world',
|
|
201
|
+
n1: 42,
|
|
202
|
+
b1: true,
|
|
203
|
+
s2: 'hello world',
|
|
204
|
+
n2: 42,
|
|
205
|
+
b2: true,
|
|
206
|
+
s3: 'hello world',
|
|
207
|
+
n3: 42,
|
|
208
|
+
b3: true,
|
|
209
|
+
s4: 'hello world',
|
|
210
|
+
n4: 42,
|
|
211
|
+
b4: true,
|
|
212
|
+
s5: 'hello world',
|
|
213
|
+
n5: 42,
|
|
214
|
+
b5: true
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
async function runBenchmark (benchmark) {
|
|
220
|
+
const worker = new Worker(BENCH_THREAD_PATH, { workerData: benchmark })
|
|
221
|
+
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
let result = null
|
|
224
|
+
worker.on('error', reject)
|
|
225
|
+
worker.on('message', (benchResult) => {
|
|
226
|
+
result = benchResult
|
|
227
|
+
})
|
|
228
|
+
worker.on('exit', (code) => {
|
|
229
|
+
if (code === 0) {
|
|
230
|
+
resolve(result)
|
|
231
|
+
} else {
|
|
232
|
+
reject(new Error(`Worker stopped with exit code ${code}`))
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function runBenchmarks () {
|
|
239
|
+
let maxNameLength = 0
|
|
240
|
+
for (const benchmark of benchmarks) {
|
|
241
|
+
maxNameLength = Math.max(benchmark.name.length, maxNameLength)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
for (const benchmark of benchmarks) {
|
|
245
|
+
benchmark.name = benchmark.name.padEnd(maxNameLength, '.')
|
|
246
|
+
const resultMessage = await runBenchmark(benchmark)
|
|
247
|
+
console.log(resultMessage)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
runBenchmarks()
|
package/example.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const fastJson = require('fast-json-stringify')
|
|
1
|
+
const fastJson = require('.')
|
|
3
2
|
const stringify = fastJson({
|
|
4
3
|
title: 'Example Schema',
|
|
5
4
|
type: 'object',
|
|
@@ -67,12 +66,10 @@ console.log(stringify({
|
|
|
67
66
|
lastName: 'Collina',
|
|
68
67
|
age: 32,
|
|
69
68
|
now: new Date(),
|
|
70
|
-
birthdate: moment(),
|
|
71
69
|
reg: /"([^"]|\\")*"/,
|
|
72
70
|
foo: 'hello',
|
|
73
71
|
numfoo: 42,
|
|
74
72
|
test: 42,
|
|
75
|
-
date: moment(),
|
|
76
73
|
strtest: '23',
|
|
77
74
|
arr: [{ str: 'stark' }, { str: 'lannister' }],
|
|
78
75
|
obj: { bool: true },
|