json-as 1.1.26 → 1.2.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 +72 -0
- package/.prettierrc.json +1 -0
- package/CHANGELOG.md +4 -0
- package/README.md +44 -59
- package/assembly/__benches__/abc.bench.ts +5 -9
- package/assembly/__benches__/large.bench.ts +114 -120
- package/assembly/__benches__/lib/bench.ts +44 -1
- package/assembly/__benches__/medium.bench.ts +108 -29
- package/assembly/__benches__/small.bench.ts +28 -18
- package/assembly/__benches__/throughput.ts +172 -0
- package/assembly/__benches__/vec3.bench.ts +8 -3
- package/assembly/__tests__/string.spec.ts +4 -0
- package/assembly/deserialize/simple/arbitrary.ts +5 -2
- package/assembly/deserialize/simple/object.ts +3 -1
- package/assembly/deserialize/swar/string.ts +62 -62
- package/assembly/index.ts +6 -2
- package/assembly/serialize/simd/string.ts +1 -1
- package/assembly/serialize/swar/number.ts +0 -0
- package/assembly/serialize/swar/string.ts +25 -25
- package/assembly/test.tmp.ts +124 -2
- package/assembly/test.ts +0 -7
- package/bench/abc.bench.ts +6 -8
- package/bench/large.bench.ts +119 -118
- package/bench/lib/bench.d.ts +27 -0
- package/bench/lib/bench.js +53 -0
- package/bench/lib/chart.ts +217 -0
- package/bench/medium.bench.ts +55 -30
- package/bench/runners/assemblyscript.js +6 -1
- package/bench/small.bench.ts +7 -3
- package/bench/throughput.ts +87 -0
- package/bench/tsconfig.json +3 -2
- package/bench/vec3.bench.ts +7 -3
- package/ci/bench/runners/assemblyscript.js +29 -0
- package/ci/run-bench.as.sh +63 -0
- package/lib/as-bs.ts +13 -0
- package/package.json +3 -1
- package/run-bench.as.sh +21 -13
- package/run-bench.js.sh +9 -7
- package/run-tests.sh +34 -14
- package/scripts/build-chart01.ts +38 -0
- package/scripts/build-chart02.ts +38 -0
- package/scripts/build-chart03.ts +139 -0
- package/scripts/build-chart05.ts +47 -0
- package/scripts/generate-as-class.ts +50 -0
- package/scripts/lib/bench-utils.ts +308 -0
- package/transform/lib/index.js +2 -2
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +2 -2
- package/assembly/__tests__/simd/string.spec.ts +0 -32
- /package/{bench → ci/bench}/lib/bench.ts +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Benchmark
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
repository_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
benchmark:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout Repository
|
|
16
|
+
uses: actions/checkout@v3
|
|
17
|
+
continue-on-error: false
|
|
18
|
+
|
|
19
|
+
- name: Setup Bun
|
|
20
|
+
uses: oven-sh/setup-bun@v1
|
|
21
|
+
continue-on-error: true
|
|
22
|
+
|
|
23
|
+
- name: Install Dependencies
|
|
24
|
+
run: bun install || true
|
|
25
|
+
continue-on-error: true
|
|
26
|
+
|
|
27
|
+
- name: Install JSVU and V8
|
|
28
|
+
run: |
|
|
29
|
+
bunx jsvu --os=linux64 --engines=v8 || true
|
|
30
|
+
echo "${HOME}/.jsvu/bin" >> $GITHUB_PATH
|
|
31
|
+
continue-on-error: true
|
|
32
|
+
|
|
33
|
+
- name: Install Binaryen
|
|
34
|
+
run: sudo apt-get update && sudo apt-get install -y binaryen || true
|
|
35
|
+
continue-on-error: true
|
|
36
|
+
|
|
37
|
+
- name: Run AssemblyScript Benchmarks
|
|
38
|
+
run: ./run-bench.as.sh || true
|
|
39
|
+
continue-on-error: true
|
|
40
|
+
|
|
41
|
+
- name: Run JavaScript Benchmarks
|
|
42
|
+
run: ./run-bench.js.sh || true
|
|
43
|
+
continue-on-error: true
|
|
44
|
+
|
|
45
|
+
- name: Build Charts
|
|
46
|
+
run: |
|
|
47
|
+
mkdir -p data
|
|
48
|
+
bun ./scripts/build-chart01.ts || true
|
|
49
|
+
bun ./scripts/build-chart02.ts || true
|
|
50
|
+
continue-on-error: true
|
|
51
|
+
|
|
52
|
+
- name: Commit Charts to docs branch
|
|
53
|
+
continue-on-error: true
|
|
54
|
+
run: |
|
|
55
|
+
set -e
|
|
56
|
+
git config user.name "github-actions"
|
|
57
|
+
git config user.email "actions@github.com"
|
|
58
|
+
|
|
59
|
+
# Ensure the docs branch exists locally
|
|
60
|
+
git fetch origin docs || true
|
|
61
|
+
if git rev-parse --verify docs >/dev/null 2>&1; then
|
|
62
|
+
git branch -D docs || true
|
|
63
|
+
fi
|
|
64
|
+
git checkout -b docs origin/docs || git checkout --orphan docs || true
|
|
65
|
+
|
|
66
|
+
# Copy generated charts
|
|
67
|
+
mkdir -p charts
|
|
68
|
+
cp data/*.svg charts/ || true
|
|
69
|
+
|
|
70
|
+
git add charts/ || true
|
|
71
|
+
git commit -m "Update benchmark charts [skip ci]" || echo "No changes to commit"
|
|
72
|
+
git push origin docs --force || true
|
package/.prettierrc.json
CHANGED
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -2,7 +2,29 @@
|
|
|
2
2
|
║╚═╗║ ║║║║══╠═╣╚═╗
|
|
3
3
|
╚╝╚═╝╚═╝╝╚╝ ╩ ╩╚═╝</pre></h1>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<details>
|
|
6
|
+
<summary>Table of Contents</summary>
|
|
7
|
+
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Usage](#usage)
|
|
10
|
+
- [Examples](#examples)
|
|
11
|
+
- [Omitting Fields](#omitting-fields)
|
|
12
|
+
- [Using Nullable Primitives](#using-nullable-primitives)
|
|
13
|
+
- [Working with Unknown or Dynamic Data](#working-with-unknown-or-dynamic-data)
|
|
14
|
+
- [Using Raw JSON Strings](#using-raw-json-strings)
|
|
15
|
+
- [Working with Enums](#working-with-enums)
|
|
16
|
+
- [Using Custom Serializers or Deserializers](#using-custom-serializers-or-deserializers)
|
|
17
|
+
- [Performance](#performance)
|
|
18
|
+
- [Comparison to JavaScript](#comparison-to-javascript)
|
|
19
|
+
- [Running Benchmarks Locally](#running-benchmarks-locally)
|
|
20
|
+
- [Re-run Benchmarks](#re-run-benchmarks)
|
|
21
|
+
- [Debugging](#debugging)
|
|
22
|
+
- [License](#license)
|
|
23
|
+
- [Contact](#contact)
|
|
24
|
+
|
|
25
|
+
</details>
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
6
28
|
|
|
7
29
|
```bash
|
|
8
30
|
npm install json-as
|
|
@@ -32,7 +54,7 @@ Alternatively, add it to your `asconfig.json`
|
|
|
32
54
|
|
|
33
55
|
If you'd like to see the code that the transform generates, run the build step with `DEBUG=true`
|
|
34
56
|
|
|
35
|
-
##
|
|
57
|
+
## Usage
|
|
36
58
|
|
|
37
59
|
```typescript
|
|
38
60
|
import { JSON } from "json-as";
|
|
@@ -78,9 +100,9 @@ console.log("Serialized " + serialized);
|
|
|
78
100
|
console.log("Deserialized " + JSON.stringify(deserialized));
|
|
79
101
|
```
|
|
80
102
|
|
|
81
|
-
##
|
|
103
|
+
## Examples
|
|
82
104
|
|
|
83
|
-
###
|
|
105
|
+
### Omitting Fields
|
|
84
106
|
|
|
85
107
|
This library allows selective omission of fields during serialization using the following decorators:
|
|
86
108
|
|
|
@@ -147,7 +169,7 @@ console.log(JSON.stringify(obj)); // { "name": "Jairus", "age": 99 }
|
|
|
147
169
|
|
|
148
170
|
If age were higher than 18, it would be included in the serialization.
|
|
149
171
|
|
|
150
|
-
###
|
|
172
|
+
### Using nullable primitives
|
|
151
173
|
|
|
152
174
|
AssemblyScript doesn't support using nullable primitive types, so instead, json-as offers the `JSON.Box` class to remedy it.
|
|
153
175
|
|
|
@@ -180,7 +202,7 @@ person.age = new JSON.Box<i32>(18); // Set age to 18
|
|
|
180
202
|
console.log(JSON.stringify(person)); // {"name":"Jairus","age":18}
|
|
181
203
|
```
|
|
182
204
|
|
|
183
|
-
###
|
|
205
|
+
### Working with unknown or dynamic data
|
|
184
206
|
|
|
185
207
|
Sometimes it's necessary to work with unknown data or data with dynamic types.
|
|
186
208
|
|
|
@@ -247,7 +269,7 @@ obj.data = JSON.Value.from("a string"); // Changing to a string
|
|
|
247
269
|
console.log(JSON.stringify(obj)); // {"id":1,"name":"Example","data":"a string"}
|
|
248
270
|
```
|
|
249
271
|
|
|
250
|
-
###
|
|
272
|
+
### Using Raw JSON strings
|
|
251
273
|
|
|
252
274
|
Sometimes its necessary to simply copy a string instead of serializing it.
|
|
253
275
|
|
|
@@ -273,7 +295,7 @@ console.log(JSON.stringify(map));
|
|
|
273
295
|
// Now its properly formatted JSON where pos's value is of type Vec3 not string!
|
|
274
296
|
```
|
|
275
297
|
|
|
276
|
-
###
|
|
298
|
+
### Working with enums
|
|
277
299
|
|
|
278
300
|
By default, enums with values other than `i32` arn't supported by AssemblyScript. However, you can use a workaround:
|
|
279
301
|
|
|
@@ -290,7 +312,7 @@ const serialized = JSON.stringify<Foo>(Foo.bar);
|
|
|
290
312
|
// "a"
|
|
291
313
|
```
|
|
292
314
|
|
|
293
|
-
###
|
|
315
|
+
### Using custom serializers or deserializers
|
|
294
316
|
|
|
295
317
|
This library supports custom serialization and deserialization methods, which can be defined using the `@serializer` and `@deserializer` decorators.
|
|
296
318
|
|
|
@@ -356,55 +378,25 @@ These functions are then wrapped before being consumed by the json-as library:
|
|
|
356
378
|
|
|
357
379
|
This allows custom serialization while maintaining a generic interface for the library to access.
|
|
358
380
|
|
|
359
|
-
##
|
|
381
|
+
## Performance
|
|
360
382
|
|
|
361
|
-
The `json-as` library
|
|
383
|
+
The `json-as` library is engineered for **multi-GB/s processing speeds**, leveraging SIMD and SWAR optimizations along with highly efficient transformations. The charts below highlight key performance metrics such as build time, operations-per-second, and throughput.
|
|
362
384
|
|
|
363
|
-
|
|
385
|
+
You can **re-run the benchmarks** at any time by clicking the button below. After the workflow completes, refresh this page to view updated results.
|
|
364
386
|
|
|
365
|
-
|
|
387
|
+
[](https://github.com/JairusSW/json-as/actions/workflows/benchmark.yml)
|
|
366
388
|
|
|
367
|
-
|
|
389
|
+
### Comparison to JavaScript
|
|
368
390
|
|
|
369
|
-
|
|
370
|
-
| --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
|
|
371
|
-
| Vector3 Object | 38 bytes | 26,611,226 ops/s | 32,160,804 ops/s | 1,357 MB/s | 1,348 MB/s |
|
|
372
|
-
| Alphabet String | 104 bytes | 16,916,886 ops/s | 18,390,804 ops/s | 1,759 MB/s | 1,986 MB/s |
|
|
373
|
-
| Small Object | 88 bytes | 24,242,424 ops/s | 12,307,692 ops/s | 2,133 MB/s | 1,083 MB/s |
|
|
374
|
-
| Medium Object | 494 bytes | 4,060,913 ops/s | 1,396,160 ops/s | 2,006 MB/s | 689.7 MB/s |
|
|
375
|
-
| Large Object | 3374 bytes | 479,616 ops/s | 132,802 ops/s | 2,074 MB/s | 448.0 MB/s |
|
|
391
|
+
The following charts compare JSON-AS (both SWAR and SIMD variants) against JavaScript's native `JSON` implementation. Benchmarks were conducted in a GitHub Actions environment. On modern hardware, you may see even higher throughput.
|
|
376
392
|
|
|
377
|
-
|
|
393
|
+
> Note: Benchmarks reflect the **latest version**. Older versions may show different performance.
|
|
378
394
|
|
|
379
|
-
|
|
380
|
-
| --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
|
|
381
|
-
| Vector3 Object | 38 bytes | 8,791,209 ops/s | 5,369,12 ops/s | 357.4 MB/s | 204.3 MB/s |
|
|
382
|
-
| Alphabet String | 104 bytes | 12,830,228 ops/s | 12,140,296 ops/s | 1,334 MB/s | 1,311 MB/s |
|
|
383
|
-
| Small Object | 88 bytes | 8,376,963 ops/s | 4,968,944 ops/s | 737.1 MB/s | 437.2 MB/s |
|
|
384
|
-
| Medium Object | 494 bytes | 2,395,210 ops/s | 1,381,693 ops/s | 1,183 MB/s | 682.5 MB/s |
|
|
385
|
-
| Large Object | 3374 bytes | 222,222 ops/s | 117,233 ops/s | 749.7 MB/s | 395.5 MB/s |
|
|
395
|
+
<img src="https://raw.githubusercontent.com/JairusSW/json-as/refs/heads/docs/data/chart01.svg" alt="Performance Chart 1">
|
|
386
396
|
|
|
387
|
-
|
|
397
|
+
<img src="https://raw.githubusercontent.com/JairusSW/json-as/refs/heads/docs/data/chart02.svg" alt="Performance Chart 2">
|
|
388
398
|
|
|
389
|
-
|
|
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** - _v0.9.29_
|
|
400
|
-
|
|
401
|
-
| Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
|
|
402
|
-
| --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
|
|
403
|
-
| Vector3 Object | 38 bytes | 6,896,551 ops/s | 10,958,904 ops/s | 262.1 MB/s | 416.4 MB/s |
|
|
404
|
-
| Alphabet String | 104 bytes | 5,128,205 ops/s | 8,695,652 ops/s | 533.3 MB/s | 939.1 MB/s |
|
|
405
|
-
| Small Object | 88 bytes | 4,953,560 ops/s | 3,678,160 ops/s | 435.9 MB/s | 323.7 MB/s |
|
|
406
|
-
| Medium Object | 494 bytes | 522,193 ops/s | 508,582 ops/s | 258.0 MB/s | 251.2 MB/s |
|
|
407
|
-
| Large Object | 3374 bytes | 51,229 ops/s | 65,585 ops/s | 172.8 MB/s | 221.3 MB/s |
|
|
399
|
+
> Note: I have focused on extensively optimizing serialization. I used to have deserialization be highly unsafe and extremely fast, but I've since doubled down on safety for deserialization which has negatively affected performance. I will be optimizing soon.
|
|
408
400
|
|
|
409
401
|
### Running benchmarks locally
|
|
410
402
|
|
|
@@ -446,24 +438,17 @@ or
|
|
|
446
438
|
./run-bench.js.sh
|
|
447
439
|
```
|
|
448
440
|
|
|
449
|
-
##
|
|
450
|
-
|
|
451
|
-
- Theorize plans to keep key-order in generated schemas
|
|
452
|
-
- Generate optimized deserialization methods
|
|
453
|
-
- Inline specific hot code paths
|
|
454
|
-
- Implement error handling implementation
|
|
455
|
-
|
|
456
|
-
## 🐛 Debugging
|
|
441
|
+
## Debugging
|
|
457
442
|
|
|
458
443
|
`JSON_DEBUG=1` - Prints out generated code at compile-time
|
|
459
444
|
`JSON_DEBUG=2` - The above and prints keys/values as they are deserialized
|
|
460
445
|
`JSON_WRITE=path-to-file.ts` - Writes out generated code to `path-to-file.json.ts` for easy inspection
|
|
461
446
|
|
|
462
|
-
##
|
|
447
|
+
## License
|
|
463
448
|
|
|
464
449
|
This project is distributed under an open source license. You can view the full license using the following link: [License](./LICENSE)
|
|
465
450
|
|
|
466
|
-
##
|
|
451
|
+
## Contact
|
|
467
452
|
|
|
468
453
|
Please send all issues to [GitHub Issues](https://github.com/JairusSW/json-as/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)
|
|
469
454
|
|
|
@@ -1,32 +1,28 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
2
|
import { expect } from "../__tests__/lib";
|
|
3
|
-
import { bench } from "./lib/bench";
|
|
3
|
+
import { bench, blackbox, dumpToFile } from "./lib/bench";
|
|
4
4
|
|
|
5
5
|
const v1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
6
6
|
const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
|
|
7
7
|
|
|
8
|
-
const blackBoxArea = memory.data(64);
|
|
9
8
|
expect(JSON.stringify(v1)).toBe(v2);
|
|
10
9
|
|
|
11
10
|
bench(
|
|
12
11
|
"Serialize Alphabet",
|
|
13
12
|
() => {
|
|
14
|
-
blackbox(inline.always(JSON.stringify(
|
|
13
|
+
blackbox(inline.always(JSON.stringify(v1)));
|
|
15
14
|
},
|
|
16
15
|
24_000_00,
|
|
17
16
|
v1.length << 1,
|
|
18
17
|
);
|
|
18
|
+
dumpToFile("abc", "serialize")
|
|
19
19
|
|
|
20
20
|
bench(
|
|
21
21
|
"Deserialize Alphabet",
|
|
22
22
|
() => {
|
|
23
|
-
blackbox(inline.always(JSON.parse<string>(
|
|
23
|
+
blackbox(inline.always(JSON.parse<string>(v2)));
|
|
24
24
|
},
|
|
25
25
|
24_000_00,
|
|
26
26
|
v2.length << 1,
|
|
27
27
|
);
|
|
28
|
-
|
|
29
|
-
function blackbox<T>(value: T): T {
|
|
30
|
-
store<T>(blackBoxArea, value);
|
|
31
|
-
return load<T>(blackBoxArea);
|
|
32
|
-
}
|
|
28
|
+
dumpToFile("abc", "deserialize")
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
2
|
import { expect } from "../__tests__/lib";
|
|
3
|
-
import { bench } from "./lib/bench";
|
|
4
|
-
|
|
3
|
+
import { bench, blackbox, dumpToFile } from "./lib/bench";
|
|
5
4
|
|
|
6
5
|
@json
|
|
7
6
|
class RepoOwner {
|
|
@@ -26,7 +25,6 @@ class RepoOwner {
|
|
|
26
25
|
public site_admin!: boolean;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
|
|
30
28
|
@json
|
|
31
29
|
class RepoLicense {
|
|
32
30
|
public key!: string;
|
|
@@ -36,7 +34,6 @@ class RepoLicense {
|
|
|
36
34
|
public node_id!: string;
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
|
|
40
37
|
@json
|
|
41
38
|
class Repo {
|
|
42
39
|
public id!: i32;
|
|
@@ -44,7 +41,7 @@ class Repo {
|
|
|
44
41
|
public name!: string;
|
|
45
42
|
public full_name!: string;
|
|
46
43
|
public private!: boolean;
|
|
47
|
-
public owner
|
|
44
|
+
public owner!: RepoOwner;
|
|
48
45
|
public html_url!: string;
|
|
49
46
|
public description!: string | null;
|
|
50
47
|
public fork!: boolean;
|
|
@@ -120,125 +117,122 @@ class Repo {
|
|
|
120
117
|
public default_branch!: string;
|
|
121
118
|
}
|
|
122
119
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
120
|
+
// Create instances and assign fields directly
|
|
121
|
+
const v1 = new Repo();
|
|
122
|
+
const owner = new RepoOwner();
|
|
123
|
+
|
|
124
|
+
owner.login = "octocat";
|
|
125
|
+
owner.id = 583231;
|
|
126
|
+
owner.node_id = "MDQ6VXNlcjU4MzIzMQ==";
|
|
127
|
+
owner.avatar_url = "https://avatars.githubusercontent.com/u/583231?v=4";
|
|
128
|
+
owner.gravatar_id = "";
|
|
129
|
+
owner.url = "https://api.github.com/users/octocat";
|
|
130
|
+
owner.html_url = "https://github.com/octocat";
|
|
131
|
+
owner.followers_url = "https://api.github.com/users/octocat/followers";
|
|
132
|
+
owner.following_url = "https://api.github.com/users/octocat/following{/other_user}";
|
|
133
|
+
owner.gists_url = "https://api.github.com/users/octocat/gists{/gist_id}";
|
|
134
|
+
owner.starred_url = "https://api.github.com/users/octocat/starred{/owner}{/repo}";
|
|
135
|
+
owner.subscriptions_url = "https://api.github.com/users/octocat/subscriptions";
|
|
136
|
+
owner.organizations_url = "https://api.github.com/users/octocat/orgs";
|
|
137
|
+
owner.repos_url = "https://api.github.com/users/octocat/repos";
|
|
138
|
+
owner.events_url = "https://api.github.com/users/octocat/events{/privacy}";
|
|
139
|
+
owner.received_events_url = "https://api.github.com/users/octocat/received_events";
|
|
140
|
+
owner.type = "User";
|
|
141
|
+
owner.user_view_type = "public";
|
|
142
|
+
owner.site_admin = false;
|
|
143
|
+
|
|
144
|
+
v1.owner = owner;
|
|
145
|
+
|
|
146
|
+
v1.id = 132935648;
|
|
147
|
+
v1.node_id = "MDEwOlJlcG9zaXRvcnkxMzI5MzU2NDg=";
|
|
148
|
+
v1.name = "boysenberry-repo-1";
|
|
149
|
+
v1.full_name = "octocat/boysenberry-repo-1";
|
|
150
|
+
v1.private = true;
|
|
151
|
+
v1.html_url = "https://github.com/octocat/boysenberry-repo-1";
|
|
152
|
+
v1.description = "Testing";
|
|
153
|
+
v1.fork = true;
|
|
154
|
+
v1.url = "https://api.github.com/repos/octocat/boysenberry-repo-1";
|
|
155
|
+
v1.forks_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/forks";
|
|
156
|
+
v1.keys_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/keys{/key_id}";
|
|
157
|
+
v1.collaborators_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/collaborators{/collaborator}";
|
|
158
|
+
v1.teams_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/teams";
|
|
159
|
+
v1.hooks_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/hooks";
|
|
160
|
+
v1.issue_events_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/issues/events{/number}";
|
|
161
|
+
v1.events_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/events";
|
|
162
|
+
v1.assignees_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/assignees{/user}";
|
|
163
|
+
v1.branches_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/branches{/branch}";
|
|
164
|
+
v1.tags_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/tags";
|
|
165
|
+
v1.blobs_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/git/blobs{/sha}";
|
|
166
|
+
v1.git_tags_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/git/tags{/sha}";
|
|
167
|
+
v1.git_refs_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/git/refs{/sha}";
|
|
168
|
+
v1.trees_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/git/trees{/sha}";
|
|
169
|
+
v1.statuses_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/statuses/{sha}";
|
|
170
|
+
v1.languages_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/languages";
|
|
171
|
+
v1.stargazers_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/stargazers";
|
|
172
|
+
v1.contributors_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/contributors";
|
|
173
|
+
v1.subscribers_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/subscribers";
|
|
174
|
+
v1.subscription_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/subscription";
|
|
175
|
+
v1.commits_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/commits{/sha}";
|
|
176
|
+
v1.git_commits_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/git/commits{/sha}";
|
|
177
|
+
v1.comments_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/comments{/number}";
|
|
178
|
+
v1.issue_comment_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/issues/comments{/number}";
|
|
179
|
+
v1.contents_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/contents/{+path}";
|
|
180
|
+
v1.compare_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/compare/{base}...{head}";
|
|
181
|
+
v1.merges_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/merges";
|
|
182
|
+
v1.archive_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/{archive_format}{/ref}";
|
|
183
|
+
v1.downloads_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/downloads";
|
|
184
|
+
v1.issues_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/issues{/number}";
|
|
185
|
+
v1.pulls_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/pulls{/number}";
|
|
186
|
+
v1.milestones_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/milestones{/number}";
|
|
187
|
+
v1.notifications_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/notifications{?since,all,participating}";
|
|
188
|
+
v1.labels_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/labels{/name}";
|
|
189
|
+
v1.releases_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/releases{/id}";
|
|
190
|
+
v1.deployments_url = "https://api.github.com/repos/octocat/boysenberry-repo-1/deployments";
|
|
191
|
+
v1.created_at = "2018-05-10T17:51:29Z";
|
|
192
|
+
v1.updated_at = "2025-05-24T02:01:19Z";
|
|
193
|
+
v1.pushed_at = "2024-05-26T07:02:05Z";
|
|
194
|
+
v1.git_url = "git://github.com/octocat/boysenberry-repo-1.git";
|
|
195
|
+
v1.ssh_url = "git@github.com:octocat/boysenberry-repo-1.git";
|
|
196
|
+
v1.clone_url = "https://github.com/octocat/boysenberry-repo-1.git";
|
|
197
|
+
v1.svn_url = "https://github.com/octocat/boysenberry-repo-1";
|
|
198
|
+
v1.homepage = "";
|
|
199
|
+
v1.size = 4;
|
|
200
|
+
v1.stargazers_count = 332;
|
|
201
|
+
v1.watchers_count = 332;
|
|
202
|
+
v1.language = null;
|
|
203
|
+
v1.has_issues = false;
|
|
204
|
+
v1.has_projects = true;
|
|
205
|
+
v1.has_downloads = true;
|
|
206
|
+
v1.has_wiki = true;
|
|
207
|
+
v1.has_pages = false;
|
|
208
|
+
v1.has_discussions = false;
|
|
209
|
+
v1.forks_count = 20;
|
|
210
|
+
v1.mirror_url = null;
|
|
211
|
+
v1.archived = false;
|
|
212
|
+
v1.disabled = false;
|
|
213
|
+
v1.open_issues_count = 1;
|
|
214
|
+
v1.license = null;
|
|
215
|
+
v1.allow_forking = true;
|
|
216
|
+
v1.is_template = false;
|
|
217
|
+
v1.web_commit_signoff_required = false;
|
|
218
|
+
v1.topics = [];
|
|
219
|
+
v1.visibility = "public";
|
|
220
|
+
v1.forks = 20;
|
|
221
|
+
v1.open_issues = 1;
|
|
222
|
+
v1.watchers = 332;
|
|
223
|
+
v1.default_branch = "master";
|
|
224
224
|
|
|
225
225
|
const v2 = `{"id":132935648,"node_id":"MDEwOlJlcG9zaXRvcnkxMzI5MzU2NDg=","name":"boysenberry-repo-1","full_name":"octocat/boysenberry-repo-1","private":true,"owner":{"login":"octocat","id":583231,"node_id":"MDQ6VXNlcjU4MzIzMQ==","avatar_url":"https://avatars.githubusercontent.com/u/583231?v=4","gravatar_id":"","url":"https://api.github.com/users/octocat","html_url":"https://github.com/octocat","followers_url":"https://api.github.com/users/octocat/followers","following_url":"https://api.github.com/users/octocat/following{/other_user}","gists_url":"https://api.github.com/users/octocat/gists{/gist_id}","starred_url":"https://api.github.com/users/octocat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/octocat/subscriptions","organizations_url":"https://api.github.com/users/octocat/orgs","repos_url":"https://api.github.com/users/octocat/repos","events_url":"https://api.github.com/users/octocat/events{/privacy}","received_events_url":"https://api.github.com/users/octocat/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/octocat/boysenberry-repo-1","description":"Testing","fork":true,"url":"https://api.github.com/repos/octocat/boysenberry-repo-1","forks_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/forks","keys_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/keys{/key_id}","collaborators_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/teams","hooks_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/hooks","issue_events_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/issues/events{/number}","events_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/events","assignees_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/assignees{/user}","branches_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/branches{/branch}","tags_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/tags","blobs_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/refs{/sha}","trees_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/trees{/sha}","statuses_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/statuses/{sha}","languages_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/languages","stargazers_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/stargazers","contributors_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/contributors","subscribers_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/subscribers","subscription_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/subscription","commits_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/commits{/sha}","git_commits_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/commits{/sha}","comments_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/comments{/number}","issue_comment_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/issues/comments{/number}","contents_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/contents/{+path}","compare_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/compare/{base}...{head}","merges_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/merges","archive_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/downloads","issues_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/issues{/number}","pulls_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/pulls{/number}","milestones_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/milestones{/number}","notifications_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/labels{/name}","releases_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/releases{/id}","deployments_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/deployments","created_at":"2018-05-10T17:51:29Z","updated_at":"2025-05-24T02:01:19Z","pushed_at":"2024-05-26T07:02:05Z","git_url":"git://github.com/octocat/boysenberry-repo-1.git","ssh_url":"git@github.com:octocat/boysenberry-repo-1.git","clone_url":"https://github.com/octocat/boysenberry-repo-1.git","svn_url":"https://github.com/octocat/boysenberry-repo-1","homepage":"","size":4,"stargazers_count":332,"watchers_count":332,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":20,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1,"license":null,"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":20,"open_issues":1,"watchers":332,"default_branch":"master"}`;
|
|
226
226
|
|
|
227
227
|
expect(JSON.stringify(v1)).toBe(v2);
|
|
228
228
|
expect(JSON.stringify(JSON.parse<Repo>(v2))).toBe(v2);
|
|
229
229
|
|
|
230
|
-
bench(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
},
|
|
235
|
-
100_00,
|
|
236
|
-
);
|
|
230
|
+
bench("Serialize Large API Response", () => {
|
|
231
|
+
blackbox(inline.always(JSON.stringify(v1)));
|
|
232
|
+
}, 10_000, 10502);
|
|
233
|
+
dumpToFile("large", "serialize")
|
|
237
234
|
|
|
238
|
-
bench(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
},
|
|
243
|
-
100_00,
|
|
244
|
-
);
|
|
235
|
+
bench("Deserialize Large API Response", () => {
|
|
236
|
+
blackbox(inline.always(JSON.parse<Repo>(v2)));
|
|
237
|
+
}, 10_000, 10502);
|
|
238
|
+
dumpToFile("large", "deserialize")
|