Skip to content

Commit d872106

Browse files
committed
chore: update readme
1 parent 64bc8db commit d872106

File tree

1 file changed

+75
-64
lines changed

1 file changed

+75
-64
lines changed

README.md

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,28 @@
66
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
77
█████ ███████ ██████ ██ ████ ██ ██ ███████
88
</span>
9-
AssemblyScript - v1.0.0-beta.17
9+
AssemblyScript - v1.0.0-beta.18
1010
</pre>
1111
</h5>
1212

1313
## 📝 About
1414

1515
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.
1616

17+
## 🚨 What's new in v1.0.0
18+
19+
🔹Breaking changes to the way custom serializers/deserializers function (See Custom Serializers below)
20+
21+
🔹Major performance improvements and addition of SIMD
22+
23+
🔹Extremely low memory overhead compared to pre-1.x.x versions (great for serverless workloads)
24+
25+
🔹Fixes to many major issues and newly discovered bugs
26+
27+
🔹Full support for dynamic objects, arrays, and values
28+
29+
🔹Full support for `JSON.Raw` type everywhere
30+
1731
## 📚 Contents
1832

1933
- [Installation](#-installation)
@@ -31,22 +45,22 @@ JSON is the de-facto serialization format of modern web applications, but its se
3145
## 💾 Installation
3246

3347
```bash
34-
npm install json-as@1.0.0-beta.17
48+
npm install json-as@1.0.0-beta.18
3549
```
3650

3751
Add the `--transform` to your `asc` command (e.g. in package.json)
3852

3953
```bash
40-
--transform json-as/transform --lib json-as/lib
54+
--transform json-as/transform --lib ./node_modules/json-as/lib
4155
```
4256

4357
Alternatively, add it to your `asconfig.json`
4458

45-
```json
59+
```typescripton
4660
{
4761
"options": {
4862
"transform": ["json-as/transform"],
49-
"lib": ["json-as/lib"]
63+
"lib": ["./node_modules/json-as/lib"]
5064
}
5165
}
5266
```
@@ -55,25 +69,29 @@ If you'd like to see the code that the transform generates, run with `JSON_DEBUG
5569

5670
## 🪄 Usage
5771

58-
```js
72+
```typescript
5973
import { JSON } from "json-as";
6074

75+
6176
@json
6277
class Vec3 {
6378
x: f32 = 0.0;
6479
y: f32 = 0.0;
6580
z: f32 = 0.0;
6681
}
6782

83+
6884
@json
6985
class Player {
86+
7087
@alias("first name")
7188
firstName!: string;
7289
lastName!: string;
7390
lastActive!: i32[];
7491
// Drop in a code block, function, or expression that evaluates to a boolean
7592
@omitif((self: Player) => self.age < 18)
7693
age!: i32;
94+
7795
@omitnull()
7896
pos!: Vec3 | null;
7997
isVerified!: boolean;
@@ -87,9 +105,9 @@ const player: Player = {
87105
pos: {
88106
x: 3.4,
89107
y: 1.2,
90-
z: 8.3
108+
z: 8.3,
91109
},
92-
isVerified: true
110+
isVerified: true,
93111
};
94112

95113
const serialized = JSON.stringify<Player>(player);
@@ -109,10 +127,12 @@ This library allows selective omission of fields during serialization using the
109127

110128
This decorator excludes a field from serialization entirely.
111129

112-
```js
130+
```typescript
131+
113132
@json
114133
class Example {
115134
name!: string;
135+
116136
@omit
117137
secret!: string;
118138
}
@@ -128,10 +148,12 @@ console.log(JSON.stringify(obj)); // { "name": "Visible" }
128148

129149
This decorator omits a field only if its value is null.
130150

131-
```js
151+
```typescript
152+
132153
@json
133154
class Example {
134155
name!: string;
156+
135157
@omitnull()
136158
optionalField!: string | null;
137159
}
@@ -147,9 +169,12 @@ console.log(JSON.stringify(obj)); // { "name": "Present" }
147169

148170
This decorator omits a field based on a custom predicate function.
149171

172+
```typescript
173+
150174
@json
151175
class Example {
152176
name!: string;
177+
153178
@omitif((self: Example) => self.age < 18)
154179
age!: number;
155180
}
@@ -169,7 +194,8 @@ AssemblyScript doesn't support using nullable primitive types, so instead, json-
169194

170195
For example, this schema won't compile in AssemblyScript:
171196

172-
```js
197+
```typescript
198+
173199
@json
174200
class Person {
175201
name!: string;
@@ -179,7 +205,8 @@ class Person {
179205

180206
Instead, use `JSON.Box` to allow nullable primitives:
181207

182-
```js
208+
```typescript
209+
183210
@json
184211
class Person {
185212
name: string;
@@ -208,7 +235,7 @@ Here's a few examples:
208235

209236
When dealing with arrays that have multiple types within them, eg. `["string",true,null,["array"]]`, use `JSON.Value[]`
210237

211-
```js
238+
```typescript
212239
const a1 = JSON.parse<JSON.Value[]>('["string",true,null,["array"]]');
213240
console.log(JSON.stringify(a[0])); // "string"
214241
console.log(JSON.stringify(a[1])); // true
@@ -220,14 +247,15 @@ console.log(JSON.stringify(a[3])); // ["array"]
220247

221248
When dealing with an object with an unknown structure, use the `JSON.Obj` type
222249

223-
```js
250+
```typescript
224251
const o1 = JSON.parse<JSON.Obj>('{"a":3.14,"b":true,"c":[1,2,3],"d":{"x":1,"y":2,"z":3}}');
225252

226253
console.log(o1.keys().join(" ")); // a b c d
227254
console.log(
228-
o1.values()
229-
.map<string>((v) => JSON.stringify(v))
230-
.join(" ")
255+
o1
256+
.values()
257+
.map<string>((v) => JSON.stringify(v))
258+
.join(" "),
231259
); // 3.14 true [1,2,3] {"x":1,"y":2,"z":3}
232260

233261
const y = o1.get("d").get<JSON.Obj>().get<i32>();
@@ -240,7 +268,8 @@ More often, objects will be completely statically typed except for one or two va
240268

241269
In such cases, `JSON.Value` can be used to handle fields that may hold different types at runtime.
242270

243-
```js
271+
```typescript
272+
244273
@json
245274
class DynamicObj {
246275
id: i32 = 0;
@@ -268,9 +297,9 @@ Sometimes its necessary to simply copy a string instead of serializing it.
268297

269298
For example, the following data would typically be serialized as:
270299

271-
```js
300+
```typescript
272301
const m1 = new Map<string, string>();
273-
m1.set('pos', '{"x":1.0,"y":2.0,"z":3.0}');
302+
m1.set("pos", '{"x":1.0,"y":2.0,"z":3.0}');
274303

275304
const a1 = JSON.stringify(m1);
276305
console.log("a1: " + a1);
@@ -280,9 +309,9 @@ console.log("a1: " + a1);
280309

281310
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:
282311

283-
```js
312+
```typescript
284313
const m1 = new Map<string, JSON.Raw>();
285-
m1.set('pos', new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
314+
m1.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
286315

287316
const a1 = JSON.stringify(m1);
288317
console.log("a1: " + a1);
@@ -296,7 +325,8 @@ This library supports custom serialization and deserialization methods, which ca
296325

297326
Here's an example of creating a custom data type called `Point` which serializes to `(x,y)`
298327

299-
```js
328+
```typescript
329+
300330
@json
301331
class Point {
302332
x: f64 = 0.0;
@@ -306,11 +336,13 @@ class Point {
306336
this.y = y;
307337
}
308338

339+
309340
@serializer
310341
serializer(self: Point): string {
311342
return `(${self.x},${self.y})`;
312343
}
313344

345+
314346
@deserializer
315347
deserializer(data: string): Point {
316348
const dataSize = bytes(data);
@@ -320,10 +352,7 @@ class Point {
320352
const x = data.slice(1, c);
321353
const y = data.slice(c + 1, data.length - 1);
322354

323-
return new Point(
324-
f64.parse(x),
325-
f64.parse(y)
326-
);
355+
return new Point(f64.parse(x), f64.parse(y));
327356
}
328357
}
329358
```
@@ -334,7 +363,7 @@ The deserializer function parses the string `(x,y)` back into a `Point` instance
334363

335364
These functions are then wrapped before being consumed by the json-as library:
336365

337-
```js
366+
```typescript
338367
@inline __SERIALIZE_CUSTOM(ptr: usize): void {
339368
const data = this.serializer(changetype<Point>(ptr));
340369
const dataSize = data.length << 1;
@@ -353,45 +382,27 @@ This allows custom serialization while maintaining a generic interface for the l
353382

354383
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.
355384

356-
### Raw Performance
357-
358-
Simple
359-
360-
| Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
361-
| ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
362-
| Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
363-
| Alphabet String | 4,928,856 ops/s | 7,567,360 ops/s | 975 MB/s | 1,498 MB/s |
364-
| Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
365-
| Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
366-
| Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
367-
368-
SIMD
369-
370-
| Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
371-
| ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
372-
| Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
373-
| Alphabet String | 20,368,584 ops/s | 28,467,424 ops/s | 3,910 MB/s | 5,636 MB/s |
374-
| Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
375-
| Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
376-
| Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
385+
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.
377386

378-
JavaScript
387+
**Table 1** - _AssemblyScript_
379388

380-
| Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
381-
| ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
382-
| Vector3 Object | 2,548,013 ops/s | 1,942,440 ops/s | 97 MB/s | 73 MB/s |
383-
| Alphabet String | 3,221,556 ops/s | 2,716,617 ops/s | 624 MB/s | 537 MB/s |
384-
| Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
385-
| Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
386-
| Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
389+
| Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
390+
| --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
391+
| Vector3 Object | 38 bytes | 35,714,285 ops/s | 35,435,552 ops/s | 1,357 MB/s | 1,348 MB/s |
392+
| Alphabet String | 104 bytes | 13,617,021 ops/s | 18,390,804 ops/s | 1,416 MB/s | 1,986 MB/s |
393+
| Small Object | 88 bytes | 24,242,424 ops/s | 12,307,692 ops/s | 2,133 MB/s | 1,083 MB/s |
394+
| Medium Object | 494 bytes | 4,060,913 ops/s | 1,396,160 ops/s | 2,006 MB/s | 689.7 MB/s |
395+
| Large Object | 3374 bytes | 614,754 ops/s | 132,802 ops/s | 2,074 MB/s | 448.0 MB/s |
387396

388-
### Real-World Usage
397+
**Table 2** - _JavaScript_
389398

390-
| Scenario | JSON Size (kb) | Serialization Time (ops/s) | Deserialization Time (ops/s) | Throughput (GB/s) |
391-
| ---------------- | -------------- | -------------------------- | ---------------------------- | ----------------- |
392-
| Web API Response | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
393-
| Database Entry | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
394-
| File Parsing | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
399+
| Test Case | Size | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
400+
| --------------- | ---------- | --------------------- | ----------------------- | -------------------- | ---------------------- |
401+
| Vector3 Object | 38 bytes | 8,791,209 ops/s | 5,369,12 ops/s | 357.4 MB/s | 204.3 MB/s |
402+
| Alphabet String | 104 bytes | 13,793,103 ops/s | 14,746,544 ops/s | 1,416 MB/s | 1,592 MB/s |
403+
| Small Object | 88 bytes | 8,376,963 ops/s | 4,968,944 ops/s | 737.1 MB/s | 437.2 MB/s |
404+
| Medium Object | 494 bytes | 2,395,210 ops/s | 1,381,693 ops/s | 1,183 MB/s | 682.5 MB/s |
405+
| Large Object | 3374 bytes | 222,222 ops/s | 117,233 ops/s | 749.7 MB/s | 395.5 MB/s |
395406

396407
## 📃 License
397408

@@ -404,4 +415,4 @@ Please send all issues to [GitHub Issues](https://github.com/JairusSW/json-as/is
404415
- **Email:** Send me inquiries, questions, or requests at [me@jairus.dev](mailto:me@jairus.dev)
405416
- **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/json-as)
406417
- **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)
407-
- **Discord:** Contact me at [My Discord](https://discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)
418+
- **Discord:** Contact me at [My Discord](https://discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)

0 commit comments

Comments
 (0)