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.
Files changed (50) hide show
  1. package/.github/workflows/benchmark.yml +72 -0
  2. package/.prettierrc.json +1 -0
  3. package/CHANGELOG.md +4 -0
  4. package/README.md +44 -59
  5. package/assembly/__benches__/abc.bench.ts +5 -9
  6. package/assembly/__benches__/large.bench.ts +114 -120
  7. package/assembly/__benches__/lib/bench.ts +44 -1
  8. package/assembly/__benches__/medium.bench.ts +108 -29
  9. package/assembly/__benches__/small.bench.ts +28 -18
  10. package/assembly/__benches__/throughput.ts +172 -0
  11. package/assembly/__benches__/vec3.bench.ts +8 -3
  12. package/assembly/__tests__/string.spec.ts +4 -0
  13. package/assembly/deserialize/simple/arbitrary.ts +5 -2
  14. package/assembly/deserialize/simple/object.ts +3 -1
  15. package/assembly/deserialize/swar/string.ts +62 -62
  16. package/assembly/index.ts +6 -2
  17. package/assembly/serialize/simd/string.ts +1 -1
  18. package/assembly/serialize/swar/number.ts +0 -0
  19. package/assembly/serialize/swar/string.ts +25 -25
  20. package/assembly/test.tmp.ts +124 -2
  21. package/assembly/test.ts +0 -7
  22. package/bench/abc.bench.ts +6 -8
  23. package/bench/large.bench.ts +119 -118
  24. package/bench/lib/bench.d.ts +27 -0
  25. package/bench/lib/bench.js +53 -0
  26. package/bench/lib/chart.ts +217 -0
  27. package/bench/medium.bench.ts +55 -30
  28. package/bench/runners/assemblyscript.js +6 -1
  29. package/bench/small.bench.ts +7 -3
  30. package/bench/throughput.ts +87 -0
  31. package/bench/tsconfig.json +3 -2
  32. package/bench/vec3.bench.ts +7 -3
  33. package/ci/bench/runners/assemblyscript.js +29 -0
  34. package/ci/run-bench.as.sh +63 -0
  35. package/lib/as-bs.ts +13 -0
  36. package/package.json +3 -1
  37. package/run-bench.as.sh +21 -13
  38. package/run-bench.js.sh +9 -7
  39. package/run-tests.sh +34 -14
  40. package/scripts/build-chart01.ts +38 -0
  41. package/scripts/build-chart02.ts +38 -0
  42. package/scripts/build-chart03.ts +139 -0
  43. package/scripts/build-chart05.ts +47 -0
  44. package/scripts/generate-as-class.ts +50 -0
  45. package/scripts/lib/bench-utils.ts +308 -0
  46. package/transform/lib/index.js +2 -2
  47. package/transform/lib/index.js.map +1 -1
  48. package/transform/src/index.ts +2 -2
  49. package/assembly/__tests__/simd/string.spec.ts +0 -32
  50. /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
@@ -1,4 +1,5 @@
1
1
  {
2
+ "pluginSearchDirs": ["node_modules"],
2
3
  "plugins": ["assemblyscript-prettier"],
3
4
  "singleQuote": false,
4
5
  "printWidth": 65536,
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 2025-12-23 - 1.2.0
4
+
5
+ - feat: Implement SWAR based algorithms, SIMD improvements, and better documentation.
6
+
3
7
  ## 2025-12-21 - 1.1.26
4
8
 
5
9
  - chore: remove log
package/README.md CHANGED
@@ -2,7 +2,29 @@
2
2
  ║╚═╗║ ║║║║══╠═╣╚═╗
3
3
  ╚╝╚═╝╚═╝╝╚╝ ╩ ╩╚═╝</pre></h1>
4
4
 
5
- ## 💾 Installation
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
- ## 🪄 Usage
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
- ## 🔍 Examples
103
+ ## Examples
82
104
 
83
- ### 🏷️ Omitting Fields
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
- ### 🗳️ Using nullable primitives
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
- ### 📤 Working with unknown or dynamic data
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
- ### 🏗️ Using Raw JSON strings
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
- ### 📝 Working with enums
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
- ### ⚒️ Using custom serializers or deserializers
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
- ## Performance
381
+ ## Performance
360
382
 
361
- 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 detailed statistics comparing performance metrics such as build time, operations-per-second, and throughput.
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
- ### 🔍 Comparison to JavaScript
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
- These benchmarks compare this library to JavaScript's native `JSON.stringify` and `JSON.parse` functions.
387
+ [![Run Benchmarks](https://img.shields.io/badge/Run_Benchmark-blue)](https://github.com/JairusSW/json-as/actions/workflows/benchmark.yml)
366
388
 
367
- **Table 1** - _AssemblyScript (LLVM)_
389
+ ### Comparison to JavaScript
368
390
 
369
- | Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
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
- **Table 2** - _JavaScript (V8)_
393
+ > Note: Benchmarks reflect the **latest version**. Older versions may show different performance.
378
394
 
379
- | Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
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
- ### 📈 Comparison to v0.9.x version
397
+ <img src="https://raw.githubusercontent.com/JairusSW/json-as/refs/heads/docs/data/chart02.svg" alt="Performance Chart 2">
388
398
 
389
- **Table 1** - _v1.0.0_
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
- ## 🔭 What's Next
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
- ## 📃 License
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
- ## 📫 Contact
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(blackbox(v1))));
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>(blackbox(v2))));
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: RepoOwner = new RepoOwner();
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
- const v1: Repo = {
124
- id: 132935648,
125
- node_id: "MDEwOlJlcG9zaXRvcnkxMzI5MzU2NDg=",
126
- name: "boysenberry-repo-1",
127
- full_name: "octocat/boysenberry-repo-1",
128
- private: true,
129
- owner: {
130
- login: "octocat",
131
- id: 583231,
132
- node_id: "MDQ6VXNlcjU4MzIzMQ==",
133
- avatar_url: "https://avatars.githubusercontent.com/u/583231?v=4",
134
- gravatar_id: "",
135
- url: "https://api.github.com/users/octocat",
136
- html_url: "https://github.com/octocat",
137
- followers_url: "https://api.github.com/users/octocat/followers",
138
- following_url: "https://api.github.com/users/octocat/following{/other_user}",
139
- gists_url: "https://api.github.com/users/octocat/gists{/gist_id}",
140
- starred_url: "https://api.github.com/users/octocat/starred{/owner}{/repo}",
141
- subscriptions_url: "https://api.github.com/users/octocat/subscriptions",
142
- organizations_url: "https://api.github.com/users/octocat/orgs",
143
- repos_url: "https://api.github.com/users/octocat/repos",
144
- events_url: "https://api.github.com/users/octocat/events{/privacy}",
145
- received_events_url: "https://api.github.com/users/octocat/received_events",
146
- type: "User",
147
- user_view_type: "public",
148
- site_admin: false,
149
- },
150
- html_url: "https://github.com/octocat/boysenberry-repo-1",
151
- description: "Testing",
152
- fork: true,
153
- url: "https://api.github.com/repos/octocat/boysenberry-repo-1",
154
- forks_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/forks",
155
- keys_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/keys{/key_id}",
156
- collaborators_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/collaborators{/collaborator}",
157
- teams_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/teams",
158
- hooks_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/hooks",
159
- issue_events_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/issues/events{/number}",
160
- events_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/events",
161
- assignees_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/assignees{/user}",
162
- branches_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/branches{/branch}",
163
- tags_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/tags",
164
- blobs_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/blobs{/sha}",
165
- git_tags_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/tags{/sha}",
166
- git_refs_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/refs{/sha}",
167
- trees_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/trees{/sha}",
168
- statuses_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/statuses/{sha}",
169
- languages_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/languages",
170
- stargazers_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/stargazers",
171
- contributors_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/contributors",
172
- subscribers_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/subscribers",
173
- subscription_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/subscription",
174
- commits_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/commits{/sha}",
175
- git_commits_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/commits{/sha}",
176
- comments_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/comments{/number}",
177
- issue_comment_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/issues/comments{/number}",
178
- contents_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/contents/{+path}",
179
- compare_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/compare/{base}...{head}",
180
- merges_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/merges",
181
- archive_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/{archive_format}{/ref}",
182
- downloads_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/downloads",
183
- issues_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/issues{/number}",
184
- pulls_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/pulls{/number}",
185
- milestones_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/milestones{/number}",
186
- notifications_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/notifications{?since,all,participating}",
187
- labels_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/labels{/name}",
188
- releases_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/releases{/id}",
189
- deployments_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/deployments",
190
- created_at: "2018-05-10T17:51:29Z",
191
- updated_at: "2025-05-24T02:01:19Z",
192
- pushed_at: "2024-05-26T07:02:05Z",
193
- git_url: "git://github.com/octocat/boysenberry-repo-1.git",
194
- ssh_url: "git@github.com:octocat/boysenberry-repo-1.git",
195
- clone_url: "https://github.com/octocat/boysenberry-repo-1.git",
196
- svn_url: "https://github.com/octocat/boysenberry-repo-1",
197
- homepage: "",
198
- size: 4,
199
- stargazers_count: 332,
200
- watchers_count: 332,
201
- language: null,
202
- has_issues: false,
203
- has_projects: true,
204
- has_downloads: true,
205
- has_wiki: true,
206
- has_pages: false,
207
- has_discussions: false,
208
- forks_count: 20,
209
- mirror_url: null,
210
- archived: false,
211
- disabled: false,
212
- open_issues_count: 1,
213
- license: null,
214
- allow_forking: true,
215
- is_template: false,
216
- web_commit_signoff_required: false,
217
- topics: [],
218
- visibility: "public",
219
- forks: 20,
220
- open_issues: 1,
221
- watchers: 332,
222
- default_branch: "master",
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
- "Serialize Large Object",
232
- () => {
233
- JSON.stringify(v1);
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
- "Deserialize Large Object",
240
- () => {
241
- JSON.parse<Repo>(v2);
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")