json-as 1.0.0-beta.16 → 1.0.0-beta.18

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.
Files changed (62) hide show
  1. package/{CHANGELOG → CHANGELOG.md} +11 -1
  2. package/README.md +80 -66
  3. package/assembly/__benches__/abc.bench.ts +22 -0
  4. package/assembly/__benches__/large.bench.ts +174 -0
  5. package/assembly/__benches__/medium.bench.ts +46 -0
  6. package/assembly/__benches__/small.bench.ts +33 -0
  7. package/assembly/__benches__/vec3.bench.ts +73 -0
  8. package/assembly/__tests__/arbitrary.spec.ts +3 -3
  9. package/assembly/__tests__/array.spec.ts +5 -8
  10. package/assembly/__tests__/box.spec.ts +10 -20
  11. package/assembly/__tests__/custom.spec.ts +7 -6
  12. package/assembly/__tests__/date.spec.ts +4 -6
  13. package/assembly/__tests__/float.spec.ts +3 -3
  14. package/assembly/__tests__/lib/index.ts +4 -0
  15. package/assembly/__tests__/map.spec.ts +1 -1
  16. package/assembly/__tests__/misc.spec.ts +90 -0
  17. package/assembly/__tests__/raw.spec.ts +3 -3
  18. package/assembly/__tests__/struct.spec.ts +3 -6
  19. package/assembly/custom/bench.ts +9 -2
  20. package/assembly/deserialize/simple/array/struct.ts +2 -3
  21. package/assembly/deserialize/simple/array.ts +1 -1
  22. package/assembly/deserialize/simple/bool.ts +1 -1
  23. package/assembly/deserialize/simple/map.ts +3 -4
  24. package/assembly/deserialize/simple/object.ts +2 -3
  25. package/assembly/deserialize/simple/raw.ts +1 -1
  26. package/assembly/deserialize/simple/struct.ts +9 -5
  27. package/assembly/index.ts +14 -5
  28. package/assembly/serialize/simple/arbitrary.ts +1 -0
  29. package/assembly/serialize/simple/array.ts +1 -0
  30. package/assembly/serialize/simple/bool.ts +1 -0
  31. package/assembly/serialize/simple/date.ts +1 -0
  32. package/assembly/serialize/simple/float.ts +1 -0
  33. package/assembly/serialize/simple/integer.ts +2 -1
  34. package/assembly/serialize/simple/map.ts +1 -0
  35. package/assembly/serialize/simple/object.ts +4 -3
  36. package/assembly/serialize/simple/raw.ts +1 -0
  37. package/assembly/serialize/simple/string.ts +1 -0
  38. package/assembly/test.ts +63 -39
  39. package/bench/abc.bench.ts +20 -0
  40. package/bench/large.bench.ts +126 -0
  41. package/bench/medium.bench.ts +43 -0
  42. package/bench/small.bench.ts +30 -0
  43. package/bench/vec3.bench.ts +26 -0
  44. package/index.ts +1 -1
  45. package/{lib → modules}/as-bs.ts +4 -13
  46. package/package.json +5 -3
  47. package/run-bench.as.sh +15 -0
  48. package/run-bench.js.sh +12 -0
  49. package/run-tests.sh +1 -1
  50. package/transform/lib/index.js +26 -46
  51. package/transform/lib/index.js.map +1 -1
  52. package/transform/src/index.ts +31 -72
  53. package/assembly/__benches__/misc.bench.ts +0 -47
  54. package/assembly/__benches__/schemas.ts +0 -25
  55. package/assembly/__benches__/string.bench.ts +0 -23
  56. package/assembly/__benches__/struct.bench.ts +0 -21
  57. package/assembly/as-bs.d.ts +0 -53
  58. package/bench/schemas.ts +0 -5
  59. package/bench/string.bench.ts +0 -16
  60. package/bench.js +0 -85
  61. /package/bench/{bench.ts → lib/bench.ts} +0 -0
  62. /package/{lib → modules}/tsconfig.json +0 -0
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 2025-03-06 - 1.0.0
4
+
5
+ - fix: object with an object as a value containing a rhs bracket or brace would exit early [3b33e94](https://github.com/JairusSW/json-as/commit/3b33e9414dc04779d22d65272863372fcd7af4a6)
6
+ - fix: objects containing properties with type Obj | null did not deserialize when using \_\_deserialize
7
+ - chore: clean up
8
+
9
+ ## 2025-03-04 - 1.0.0-beta.17
10
+
11
+ - fix: forgot to build transform
12
+
3
13
  ## 2025-03-04 - 1.0.0-beta.16
4
14
 
5
15
  - fix: isPrimitive should only trigger on actual primitives
@@ -128,4 +138,4 @@
128
138
  - feat: reduce memory usage so that it is viable for low-memory environments
129
139
  - feat: write to a central buffer and reduce memory overhead
130
140
  - feat: rewrite the transform to properly resolve schemas and link them together
131
- - feat: pre-allocate and compute the minimum size of a schema to avoid memory out of range errors
141
+ - feat: pre-allocate and compute the minimum size of a schema to avoid memory out of range errors
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
7
7
  █████ ███████ ██████ ██ ████ ██ ██ ███████
8
8
  </span>
9
- AssemblyScript - v1.0.0-beta.16
9
+ AssemblyScript - v1.0.0-beta.18
10
10
  </pre>
11
11
  </h5>
12
12
 
@@ -14,6 +14,22 @@
14
14
 
15
15
  JSON is the de-facto serialization format of modern web applications, but its serialization and deserialization remain a significant performance bottleneck, especially at scale. Traditional parsing approaches are computationally expensive, adding unnecessary overhead to both clients and servers. This library is designed to mitigate this by leveraging SIMD acceleration and highly optimized transformations.
16
16
 
17
+ ## 🚨 What's new in v1.0.0
18
+
19
+ 🔹First release of `v1.0.0`
20
+
21
+ 🔹Breaking changes to the way custom serializers/deserializers function (See Custom Serializers below)
22
+
23
+ 🔹Major performance improvements and addition of SIMD
24
+
25
+ 🔹Extremely low memory overhead compared to pre-1.x.x versions (great for serverless workloads)
26
+
27
+ 🔹Fixes to many major issues and newly discovered bugs
28
+
29
+ 🔹Full support for dynamic objects, arrays, and values
30
+
31
+ 🔹Full support for `JSON.Raw` type everywhere
32
+
17
33
  ## 📚 Contents
18
34
 
19
35
  - [Installation](#-installation)
@@ -31,7 +47,7 @@ JSON is the de-facto serialization format of modern web applications, but its se
31
47
  ## 💾 Installation
32
48
 
33
49
  ```bash
34
- npm install json-as@1.0.0-beta.16
50
+ npm install json-as@1.0.0-beta.18
35
51
  ```
36
52
 
37
53
  Add the `--transform` to your `asc` command (e.g. in package.json)
@@ -42,7 +58,7 @@ Add the `--transform` to your `asc` command (e.g. in package.json)
42
58
 
43
59
  Alternatively, add it to your `asconfig.json`
44
60
 
45
- ```json
61
+ ```typescripton
46
62
  {
47
63
  "options": {
48
64
  "transform": ["json-as/transform"],
@@ -55,9 +71,10 @@ If you'd like to see the code that the transform generates, run with `JSON_DEBUG
55
71
 
56
72
  ## 🪄 Usage
57
73
 
58
- ```js
74
+ ```typescript
59
75
  import { JSON } from "json-as";
60
76
 
77
+
61
78
  @json
62
79
  class Vec3 {
63
80
  x: f32 = 0.0;
@@ -65,8 +82,10 @@ class Vec3 {
65
82
  z: f32 = 0.0;
66
83
  }
67
84
 
85
+
68
86
  @json
69
87
  class Player {
88
+
70
89
  @alias("first name")
71
90
  firstName!: string;
72
91
  lastName!: string;
@@ -74,6 +93,7 @@ class Player {
74
93
  // Drop in a code block, function, or expression that evaluates to a boolean
75
94
  @omitif((self: Player) => self.age < 18)
76
95
  age!: i32;
96
+
77
97
  @omitnull()
78
98
  pos!: Vec3 | null;
79
99
  isVerified!: boolean;
@@ -87,9 +107,9 @@ const player: Player = {
87
107
  pos: {
88
108
  x: 3.4,
89
109
  y: 1.2,
90
- z: 8.3
110
+ z: 8.3,
91
111
  },
92
- isVerified: true
112
+ isVerified: true,
93
113
  };
94
114
 
95
115
  const serialized = JSON.stringify<Player>(player);
@@ -109,10 +129,12 @@ This library allows selective omission of fields during serialization using the
109
129
 
110
130
  This decorator excludes a field from serialization entirely.
111
131
 
112
- ```js
132
+ ```typescript
133
+
113
134
  @json
114
135
  class Example {
115
136
  name!: string;
137
+
116
138
  @omit
117
139
  secret!: string;
118
140
  }
@@ -128,10 +150,12 @@ console.log(JSON.stringify(obj)); // { "name": "Visible" }
128
150
 
129
151
  This decorator omits a field only if its value is null.
130
152
 
131
- ```js
153
+ ```typescript
154
+
132
155
  @json
133
156
  class Example {
134
157
  name!: string;
158
+
135
159
  @omitnull()
136
160
  optionalField!: string | null;
137
161
  }
@@ -141,14 +165,18 @@ obj.name = "Present";
141
165
  obj.optionalField = null;
142
166
 
143
167
  console.log(JSON.stringify(obj)); // { "name": "Present" }
168
+ ```
144
169
 
145
- @omitif((self: this) => condition)
170
+ **@omitif((self: this) => condition)**
146
171
 
147
172
  This decorator omits a field based on a custom predicate function.
148
173
 
174
+ ```typescript
175
+
149
176
  @json
150
177
  class Example {
151
178
  name!: string;
179
+
152
180
  @omitif((self: Example) => self.age < 18)
153
181
  age!: number;
154
182
  }
@@ -168,7 +196,8 @@ AssemblyScript doesn't support using nullable primitive types, so instead, json-
168
196
 
169
197
  For example, this schema won't compile in AssemblyScript:
170
198
 
171
- ```js
199
+ ```typescript
200
+
172
201
  @json
173
202
  class Person {
174
203
  name!: string;
@@ -178,7 +207,8 @@ class Person {
178
207
 
179
208
  Instead, use `JSON.Box` to allow nullable primitives:
180
209
 
181
- ```js
210
+ ```typescript
211
+
182
212
  @json
183
213
  class Person {
184
214
  name: string;
@@ -207,7 +237,7 @@ Here's a few examples:
207
237
 
208
238
  When dealing with arrays that have multiple types within them, eg. `["string",true,null,["array"]]`, use `JSON.Value[]`
209
239
 
210
- ```js
240
+ ```typescript
211
241
  const a1 = JSON.parse<JSON.Value[]>('["string",true,null,["array"]]');
212
242
  console.log(JSON.stringify(a[0])); // "string"
213
243
  console.log(JSON.stringify(a[1])); // true
@@ -219,14 +249,15 @@ console.log(JSON.stringify(a[3])); // ["array"]
219
249
 
220
250
  When dealing with an object with an unknown structure, use the `JSON.Obj` type
221
251
 
222
- ```js
252
+ ```typescript
223
253
  const o1 = JSON.parse<JSON.Obj>('{"a":3.14,"b":true,"c":[1,2,3],"d":{"x":1,"y":2,"z":3}}');
224
254
 
225
255
  console.log(o1.keys().join(" ")); // a b c d
226
256
  console.log(
227
- o1.values()
228
- .map<string>((v) => JSON.stringify(v))
229
- .join(" ")
257
+ o1
258
+ .values()
259
+ .map<string>((v) => JSON.stringify(v))
260
+ .join(" "),
230
261
  ); // 3.14 true [1,2,3] {"x":1,"y":2,"z":3}
231
262
 
232
263
  const y = o1.get("d").get<JSON.Obj>().get<i32>();
@@ -239,7 +270,8 @@ More often, objects will be completely statically typed except for one or two va
239
270
 
240
271
  In such cases, `JSON.Value` can be used to handle fields that may hold different types at runtime.
241
272
 
242
- ```js
273
+ ```typescript
274
+
243
275
  @json
244
276
  class DynamicObj {
245
277
  id: i32 = 0;
@@ -267,9 +299,9 @@ Sometimes its necessary to simply copy a string instead of serializing it.
267
299
 
268
300
  For example, the following data would typically be serialized as:
269
301
 
270
- ```js
302
+ ```typescript
271
303
  const m1 = new Map<string, string>();
272
- m1.set('pos', '{"x":1.0,"y":2.0,"z":3.0}');
304
+ m1.set("pos", '{"x":1.0,"y":2.0,"z":3.0}');
273
305
 
274
306
  const a1 = JSON.stringify(m1);
275
307
  console.log("a1: " + a1);
@@ -279,9 +311,9 @@ console.log("a1: " + a1);
279
311
 
280
312
  If, instead, one wanted to insert Raw JSON into an existing schema/data structure, they could make use of the JSON.Raw type to do so:
281
313
 
282
- ```js
314
+ ```typescript
283
315
  const m1 = new Map<string, JSON.Raw>();
284
- m1.set('pos', new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
316
+ m1.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
285
317
 
286
318
  const a1 = JSON.stringify(m1);
287
319
  console.log("a1: " + a1);
@@ -295,7 +327,8 @@ This library supports custom serialization and deserialization methods, which ca
295
327
 
296
328
  Here's an example of creating a custom data type called `Point` which serializes to `(x,y)`
297
329
 
298
- ```js
330
+ ```typescript
331
+
299
332
  @json
300
333
  class Point {
301
334
  x: f64 = 0.0;
@@ -305,11 +338,13 @@ class Point {
305
338
  this.y = y;
306
339
  }
307
340
 
341
+
308
342
  @serializer
309
343
  serializer(self: Point): string {
310
344
  return `(${self.x},${self.y})`;
311
345
  }
312
346
 
347
+
313
348
  @deserializer
314
349
  deserializer(data: string): Point {
315
350
  const dataSize = bytes(data);
@@ -319,10 +354,7 @@ class Point {
319
354
  const x = data.slice(1, c);
320
355
  const y = data.slice(c + 1, data.length - 1);
321
356
 
322
- return new Point(
323
- f64.parse(x),
324
- f64.parse(y)
325
- );
357
+ return new Point(f64.parse(x), f64.parse(y));
326
358
  }
327
359
  }
328
360
  ```
@@ -333,7 +365,7 @@ The deserializer function parses the string `(x,y)` back into a `Point` instance
333
365
 
334
366
  These functions are then wrapped before being consumed by the json-as library:
335
367
 
336
- ```js
368
+ ```typescript
337
369
  @inline __SERIALIZE_CUSTOM(ptr: usize): void {
338
370
  const data = this.serializer(changetype<Point>(ptr));
339
371
  const dataSize = data.length << 1;
@@ -352,45 +384,27 @@ This allows custom serialization while maintaining a generic interface for the l
352
384
 
353
385
  The `json-as` library has been optimized to achieve near-gigabyte-per-second JSON processing speeds through SIMD acceleration and highly efficient transformations. Below are some key performance benchmarks to give you an idea of how it performs.
354
386
 
355
- ### Raw Performance
356
-
357
- Simple
358
-
359
- | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
360
- | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
361
- | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
362
- | Alphabet String | 4,928,856 ops/s | 7,567,360 ops/s | 975 MB/s | 1,498 MB/s |
363
- | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
364
- | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
365
- | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
366
-
367
- SIMD
368
-
369
- | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
370
- | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
371
- | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
372
- | Alphabet String | 20,368,584 ops/s | 28,467,424 ops/s | 3,910 MB/s | 5,636 MB/s |
373
- | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
374
- | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
375
- | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
376
-
377
- JavaScript
378
-
379
- | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
380
- | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
381
- | Vector3 Object | 2,548,013 ops/s | 1,942,440 ops/s | 97 MB/s | 73 MB/s |
382
- | Alphabet String | 3,221,556 ops/s | 2,716,617 ops/s | 624 MB/s | 537 MB/s |
383
- | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
384
- | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
385
- | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
386
-
387
- ### Real-World Usage
388
-
389
- | Scenario | JSON Size (kb) | Serialization Time (ops/s) | Deserialization Time (ops/s) | Throughput (GB/s) |
390
- | ---------------- | -------------- | -------------------------- | ---------------------------- | ----------------- |
391
- | Web API Response | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
392
- | Database Entry | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
393
- | File Parsing | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
387
+ Note: the AssemblyScript benches are run using a _bump allocator_ so that Garbage Collection does not interfere with results. Also note that ideally, I would use [d8](https://v8.dev/docs/d8), but until that is done, these results serve as a temporary performance comparison.
388
+
389
+ **Table 1** - _AssemblyScript_
390
+
391
+ | Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
392
+ | --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
393
+ | Vector3 Object | 38 bytes | 35,714,285 ops/s | 35,435,552 ops/s | 1,357 MB/s | 1,348 MB/s |
394
+ | Alphabet String | 104 bytes | 13,617,021 ops/s | 18,390,804 ops/s | 1,416 MB/s | 1,986 MB/s |
395
+ | Small Object | 88 bytes | 24,242,424 ops/s | 12,307,692 ops/s | 2,133 MB/s | 1,083 MB/s |
396
+ | Medium Object | 494 bytes | 4,060,913 ops/s | 1,396,160 ops/s | 2,006 MB/s | 689.7 MB/s |
397
+ | Large Object | 3374 bytes | 614,754 ops/s | 132,802 ops/s | 2,074 MB/s | 448.0 MB/s |
398
+
399
+ **Table 2** - _JavaScript_
400
+
401
+ | Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
402
+ | --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
403
+ | Vector3 Object | 38 bytes | 8,791,209 ops/s | 5,369,12 ops/s | 357.4 MB/s | 204.3 MB/s |
404
+ | Alphabet String | 104 bytes | 13,793,103 ops/s | 14,746,544 ops/s | 1,416 MB/s | 1,592 MB/s |
405
+ | Small Object | 88 bytes | 8,376,963 ops/s | 4,968,944 ops/s | 737.1 MB/s | 437.2 MB/s |
406
+ | Medium Object | 494 bytes | 2,395,210 ops/s | 1,381,693 ops/s | 1,183 MB/s | 682.5 MB/s |
407
+ | Large Object | 3374 bytes | 222,222 ops/s | 117,233 ops/s | 749.7 MB/s | 395.5 MB/s |
394
408
 
395
409
  ## 📃 License
396
410
 
@@ -0,0 +1,22 @@
1
+ import { JSON } from "..";
2
+ import { bs } from "../../modules/as-bs";
3
+ import { bench } from "../custom/bench";
4
+
5
+ const v1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
6
+ const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
7
+
8
+ bench(
9
+ "Serialize Alphabet",
10
+ () => {
11
+ JSON.stringify(v1);
12
+ },
13
+ 64_000_00,
14
+ );
15
+
16
+ bench(
17
+ "Deserialize Alphabet",
18
+ () => {
19
+ JSON.parse<string>(v2);
20
+ },
21
+ 64_000_00,
22
+ );
@@ -0,0 +1,174 @@
1
+ import { JSON } from "..";
2
+ import { bench } from "../custom/bench";
3
+
4
+
5
+ @json
6
+ class Vec3 {
7
+ public x!: i32;
8
+ public y!: i32;
9
+ public z!: i32;
10
+
11
+ @inline __SERIALIZE(ptr: usize): void {
12
+ bs.proposeSize(98);
13
+ store<u64>(bs.offset, 9570664606466171, 0); // {"x"
14
+ store<u16>(bs.offset, 58, 8); // :
15
+ bs.offset += 10;
16
+ JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("x")));
17
+ store<u64>(bs.offset, 9570668901433388, 0); // ,"y"
18
+ store<u16>(bs.offset, 58, 8); // :
19
+ bs.offset += 10;
20
+ JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("y")));
21
+ store<u64>(bs.offset, 9570673196400684, 0); // ,"z"
22
+ store<u16>(bs.offset, 58, 8); // :
23
+ bs.offset += 10;
24
+ JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("z")));
25
+ store<u16>(bs.offset, 125, 0); // }
26
+ bs.offset += 2;
27
+ }
28
+
29
+ @inline __INITIALIZE(): this {
30
+ return this;
31
+ }
32
+
33
+ @inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {
34
+ switch (load<u16>(keyStart)) {
35
+ case 120: {
36
+ // x
37
+ store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("x"));
38
+ return;
39
+ }
40
+ case 121: {
41
+ // y
42
+ store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("y"));
43
+ return;
44
+ }
45
+ case 122: {
46
+ // z
47
+ store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("z"));
48
+ return;
49
+ }
50
+ }
51
+ return;
52
+ }
53
+ }
54
+
55
+
56
+ @json
57
+ class LargeJSON {
58
+ public id!: i32;
59
+ public name!: string;
60
+ public age!: i32;
61
+ public email!: string;
62
+ public street!: string;
63
+ public city!: string;
64
+ public state!: string;
65
+ public zip!: string;
66
+ public tags!: string[];
67
+ public theme!: string;
68
+ public notifications!: boolean;
69
+ public language!: string;
70
+ public movement!: Vec3[];
71
+ }
72
+
73
+ const v1: LargeJSON = {
74
+ id: 2,
75
+ name: "Medium Object",
76
+ age: 18,
77
+ email: "me@jairus.dev",
78
+ street: "I don't want to say my street",
79
+ city: "I don't want to say this either",
80
+ state: "It really depends",
81
+ zip: "I forget what it is",
82
+ tags: ["me", "dogs", "mountains", "bar", "foo"],
83
+ theme: "Hyper Term Black",
84
+ notifications: true,
85
+ language: "en-US",
86
+ movement: [
87
+ { x: 1, y: 2, z: 3 },
88
+ { x: 1, y: 2, z: 3 },
89
+ { x: 1, y: 2, z: 3 },
90
+ { x: 1, y: 2, z: 3 },
91
+ { x: 1, y: 2, z: 3 },
92
+ { x: 1, y: 2, z: 3 },
93
+ { x: 1, y: 2, z: 3 },
94
+ { x: 1, y: 2, z: 3 },
95
+ { x: 1, y: 2, z: 3 },
96
+ { x: 1, y: 2, z: 3 },
97
+ { x: 1, y: 2, z: 3 },
98
+ { x: 1, y: 2, z: 3 },
99
+ { x: 1, y: 2, z: 3 },
100
+ { x: 1, y: 2, z: 3 },
101
+ { x: 1, y: 2, z: 3 },
102
+ { x: 1, y: 2, z: 3 },
103
+ { x: 1, y: 2, z: 3 },
104
+ { x: 1, y: 2, z: 3 },
105
+ { x: 1, y: 2, z: 3 },
106
+ { x: 1, y: 2, z: 3 },
107
+ { x: 1, y: 2, z: 3 },
108
+ { x: 1, y: 2, z: 3 },
109
+ { x: 1, y: 2, z: 3 },
110
+ { x: 1, y: 2, z: 3 },
111
+ { x: 1, y: 2, z: 3 },
112
+ { x: 1, y: 2, z: 3 },
113
+ { x: 1, y: 2, z: 3 },
114
+ { x: 1, y: 2, z: 3 },
115
+ { x: 1, y: 2, z: 3 },
116
+ { x: 1, y: 2, z: 3 },
117
+ { x: 1, y: 2, z: 3 },
118
+ { x: 1, y: 2, z: 3 },
119
+ { x: 1, y: 2, z: 3 },
120
+ { x: 1, y: 2, z: 3 },
121
+ { x: 1, y: 2, z: 3 },
122
+ { x: 1, y: 2, z: 3 },
123
+ { x: 1, y: 2, z: 3 },
124
+ { x: 1, y: 2, z: 3 },
125
+ { x: 1, y: 2, z: 3 },
126
+ { x: 1, y: 2, z: 3 },
127
+ { x: 1, y: 2, z: 3 },
128
+ { x: 1, y: 2, z: 3 },
129
+ { x: 1, y: 2, z: 3 },
130
+ { x: 1, y: 2, z: 3 },
131
+ { x: 1, y: 2, z: 3 },
132
+ { x: 1, y: 2, z: 3 },
133
+ { x: 1, y: 2, z: 3 },
134
+ { x: 1, y: 2, z: 3 },
135
+ { x: 1, y: 2, z: 3 },
136
+ { x: 1, y: 2, z: 3 },
137
+ { x: 1, y: 2, z: 3 },
138
+ { x: 1, y: 2, z: 3 },
139
+ { x: 1, y: 2, z: 3 },
140
+ { x: 1, y: 2, z: 3 },
141
+ { x: 1, y: 2, z: 3 },
142
+ { x: 1, y: 2, z: 3 },
143
+ { x: 1, y: 2, z: 3 },
144
+ { x: 1, y: 2, z: 3 },
145
+ { x: 1, y: 2, z: 3 },
146
+ { x: 1, y: 2, z: 3 },
147
+ { x: 1, y: 2, z: 3 },
148
+ { x: 1, y: 2, z: 3 },
149
+ { x: 1, y: 2, z: 3 },
150
+ { x: 1, y: 2, z: 3 },
151
+ { x: 1, y: 2, z: 3 },
152
+ { x: 1, y: 2, z: 3 },
153
+ { x: 1, y: 2, z: 3 },
154
+ { x: 1, y: 2, z: 3 },
155
+ ],
156
+ };
157
+
158
+ const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"],"theme":"Hyper Term Black","notifications":true,"language":"en-US","movement":[{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3}]}`;
159
+
160
+ bench(
161
+ "Serialize Medium Object",
162
+ () => {
163
+ JSON.stringify(v1);
164
+ },
165
+ 3_000_00,
166
+ );
167
+
168
+ bench(
169
+ "Deserialize Medium Object",
170
+ () => {
171
+ JSON.parse<LargeJSON>(v2);
172
+ },
173
+ 3_000_00,
174
+ );
@@ -0,0 +1,46 @@
1
+ import { JSON } from "..";
2
+ import { bench } from "../custom/bench";
3
+
4
+
5
+ @json
6
+ class MediumJSON {
7
+ public id!: i32;
8
+ public name!: string;
9
+ public age!: i32;
10
+ public email!: string;
11
+ public street!: string;
12
+ public city!: string;
13
+ public state!: string;
14
+ public zip!: string;
15
+ public tags!: string[];
16
+ }
17
+
18
+ const v1: MediumJSON = {
19
+ id: 2,
20
+ name: "Medium Object",
21
+ age: 18,
22
+ email: "me@jairus.dev",
23
+ street: "I don't want to say my street",
24
+ city: "I don't want to say this either",
25
+ state: "It really depends",
26
+ zip: "I forget what it is",
27
+ tags: ["me", "dogs", "mountains", "bar", "foo"],
28
+ };
29
+
30
+ const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"]}`;
31
+
32
+ bench(
33
+ "Serialize Medium Object",
34
+ () => {
35
+ JSON.stringify(v1);
36
+ },
37
+ 8_000_00,
38
+ );
39
+
40
+ bench(
41
+ "Deserialize Medium Object",
42
+ () => {
43
+ JSON.parse<MediumJSON>(v2);
44
+ },
45
+ 8_000_00,
46
+ );
@@ -0,0 +1,33 @@
1
+ import { JSON } from "..";
2
+ import { bench } from "../custom/bench";
3
+
4
+
5
+ @json
6
+ class SmallJSON {
7
+ public id!: i32;
8
+ public name!: string;
9
+ public active!: boolean;
10
+ }
11
+
12
+ const v1: SmallJSON = {
13
+ id: 1,
14
+ name: "Small Object",
15
+ active: true,
16
+ };
17
+ const v2 = '{"id":1,"name":"Small Object","active":true}';
18
+
19
+ bench(
20
+ "Serialize Small Object",
21
+ () => {
22
+ JSON.stringify(v1);
23
+ },
24
+ 16_000_00,
25
+ );
26
+
27
+ bench(
28
+ "Deserialize Small Object",
29
+ () => {
30
+ JSON.parse<SmallJSON>(v2);
31
+ },
32
+ 16_000_00,
33
+ );