json-as 1.0.0 → 1.0.2
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/{nodejs.yml → tests.yml} +1 -1
- package/CHANGELOG.md +8 -0
- package/README.md +60 -12
- package/assembly/__benches__/abc.bench.ts +21 -0
- package/assembly/__benches__/large.bench.ts +174 -0
- package/assembly/__benches__/lib/index.ts +26 -0
- package/assembly/__benches__/medium.bench.ts +46 -0
- package/assembly/__benches__/small.bench.ts +33 -0
- package/assembly/__benches__/vec3.bench.ts +72 -0
- package/assembly/__tests__/struct.spec.ts +20 -22
- package/assembly/deserialize/simple/bool.ts +2 -1
- package/assembly/deserialize/simple/date.ts +2 -1
- package/assembly/deserialize/simple/float.ts +2 -1
- package/assembly/deserialize/simple/raw.ts +2 -1
- package/assembly/deserialize/simple/string.ts +2 -1
- package/assembly/deserialize/simple/struct.ts +0 -1
- package/assembly/index.ts +65 -58
- package/assembly/serialize/simple/float.ts +2 -1
- package/assembly/serialize/simple/integer.ts +2 -1
- package/assembly/serialize/simple/raw.ts +2 -1
- package/assembly/serialize/simple/string.ts +2 -1
- package/assembly/test.ts +12 -1
- package/bench/abc.bench.ts +20 -0
- package/bench/large.bench.ts +126 -0
- package/bench/medium.bench.ts +43 -0
- package/bench/small.bench.ts +30 -0
- package/bench/vec3.bench.ts +26 -0
- package/package.json +28 -31
- package/run-bench.as.sh +27 -0
- package/run-bench.js.sh +12 -0
- package/run-tests.sh +14 -2
- package/transform/lib/index.js +2 -2
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +2 -2
- package/assembly/__benches__/misc.bench.ts +0 -47
- package/assembly/__benches__/schemas.ts +0 -25
- package/assembly/__benches__/string.bench.ts +0 -23
- package/assembly/__benches__/struct.bench.ts +0 -21
- package/bench/schemas.ts +0 -5
- package/bench/string.bench.ts +0 -16
- /package/bench/{bench.ts → lib/bench.ts} +0 -0
package/assembly/index.ts
CHANGED
|
@@ -118,12 +118,12 @@ export namespace JSON {
|
|
|
118
118
|
// @ts-ignore: Supplied by transform
|
|
119
119
|
} else if (isDefined(data.__SERIALIZE_CUSTOM)) {
|
|
120
120
|
// @ts-ignore
|
|
121
|
-
data.__SERIALIZE_CUSTOM(changetype<usize>(data));
|
|
121
|
+
inline.always(data.__SERIALIZE_CUSTOM(changetype<usize>(data)));
|
|
122
122
|
return bs.out<string>();
|
|
123
123
|
// @ts-ignore: Supplied by transform
|
|
124
124
|
} else if (isDefined(data.__SERIALIZE)) {
|
|
125
125
|
// @ts-ignore
|
|
126
|
-
data.__SERIALIZE(changetype<usize>(data));
|
|
126
|
+
inline.always(data.__SERIALIZE(changetype<usize>(data)));
|
|
127
127
|
return bs.out<string>();
|
|
128
128
|
// @ts-ignore: Supplied by transform
|
|
129
129
|
} else if (data instanceof Date) {
|
|
@@ -135,20 +135,20 @@ export namespace JSON {
|
|
|
135
135
|
return changetype<string>(out);
|
|
136
136
|
} else if (data instanceof Array) {
|
|
137
137
|
// @ts-ignore
|
|
138
|
-
serializeArray(changetype<nonnull<T>>(data));
|
|
138
|
+
inline.always(serializeArray(changetype<nonnull<T>>(data)));
|
|
139
139
|
return bs.out<string>();
|
|
140
140
|
} else if (data instanceof Map) {
|
|
141
141
|
// @ts-ignore
|
|
142
|
-
serializeMap(changetype<nonnull<T>>(data));
|
|
142
|
+
inline.always(serializeMap(changetype<nonnull<T>>(data)));
|
|
143
143
|
return bs.out<string>();
|
|
144
144
|
} else if (data instanceof JSON.Raw) {
|
|
145
|
-
serializeRaw(data);
|
|
145
|
+
inline.always(serializeRaw(data));
|
|
146
146
|
return bs.out<string>();
|
|
147
147
|
} else if (data instanceof JSON.Value) {
|
|
148
|
-
serializeArbitrary(data);
|
|
148
|
+
inline.always(serializeArbitrary(data));
|
|
149
149
|
return bs.out<string>();
|
|
150
150
|
} else if (data instanceof JSON.Obj) {
|
|
151
|
-
serializeObject(data);
|
|
151
|
+
inline.always(serializeObject(data));
|
|
152
152
|
return bs.out<string>();
|
|
153
153
|
} else if (data instanceof JSON.Box) {
|
|
154
154
|
return JSON.stringify(data.value);
|
|
@@ -183,43 +183,44 @@ export namespace JSON {
|
|
|
183
183
|
return deserializeString(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>()));
|
|
184
184
|
} else if (isArray<T>()) {
|
|
185
185
|
// @ts-ignore
|
|
186
|
-
return deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>()));
|
|
187
|
-
}
|
|
188
|
-
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
189
|
-
// @ts-ignore: Defined by transform
|
|
190
|
-
if (isDefined(type.__DESERIALIZE_CUSTOM)) {
|
|
191
|
-
const out = changetype<nonnull<T>>(0);
|
|
192
|
-
// @ts-ignore: Defined by transform
|
|
193
|
-
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
|
|
194
|
-
// @ts-ignore
|
|
195
|
-
return out.__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
|
|
196
|
-
// @ts-ignore: Defined by transform
|
|
197
|
-
} else if (isDefined(type.__DESERIALIZE)) {
|
|
198
|
-
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
|
|
199
|
-
// @ts-ignore: Defined by transform
|
|
200
|
-
if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
|
|
201
|
-
// @ts-ignore
|
|
202
|
-
return deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
|
|
203
|
-
} else if (type instanceof Map) {
|
|
204
|
-
// @ts-ignore
|
|
205
|
-
return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0);
|
|
206
|
-
} else if (type instanceof Date) {
|
|
207
|
-
// @ts-ignore
|
|
208
|
-
return deserializeDate(dataPtr, dataPtr + dataSize);
|
|
209
|
-
} else if (type instanceof JSON.Raw) {
|
|
210
|
-
// @ts-ignore: type
|
|
211
|
-
return deserializeRaw(dataPtr, dataPtr + dataSize);
|
|
212
|
-
} else if (type instanceof JSON.Value) {
|
|
213
|
-
// @ts-ignorew
|
|
214
|
-
return deserializeArbitrary(dataPtr, dataPtr + dataSize, 0);
|
|
215
|
-
} else if (type instanceof JSON.Obj) {
|
|
216
|
-
// @ts-ignore
|
|
217
|
-
return deserializeObject(dataPtr, dataPtr + dataSize, 0);
|
|
218
|
-
} else if (type instanceof JSON.Box) {
|
|
219
|
-
// @ts-ignore
|
|
220
|
-
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
|
|
186
|
+
return inline.always(deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>())));
|
|
221
187
|
} else {
|
|
222
|
-
|
|
188
|
+
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
189
|
+
// @ts-ignore: Defined by transform
|
|
190
|
+
if (isDefined(type.__DESERIALIZE_CUSTOM)) {
|
|
191
|
+
const out = changetype<nonnull<T>>(0);
|
|
192
|
+
// @ts-ignore: Defined by transform
|
|
193
|
+
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
|
|
194
|
+
// @ts-ignore
|
|
195
|
+
return out.__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
|
|
196
|
+
// @ts-ignore: Defined by transform
|
|
197
|
+
} else if (isDefined(type.__DESERIALIZE)) {
|
|
198
|
+
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
|
|
199
|
+
// @ts-ignore: Defined by transform
|
|
200
|
+
if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
|
|
201
|
+
// @ts-ignore
|
|
202
|
+
return inline.always(deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out));
|
|
203
|
+
} else if (type instanceof Map) {
|
|
204
|
+
// @ts-ignore
|
|
205
|
+
return inline.always(deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0));
|
|
206
|
+
} else if (type instanceof Date) {
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
return deserializeDate(dataPtr, dataPtr + dataSize);
|
|
209
|
+
} else if (type instanceof JSON.Raw) {
|
|
210
|
+
// @ts-ignore: type
|
|
211
|
+
return deserializeRaw(dataPtr, dataPtr + dataSize);
|
|
212
|
+
} else if (type instanceof JSON.Value) {
|
|
213
|
+
// @ts-ignore
|
|
214
|
+
return inline.always(deserializeArbitrary(dataPtr, dataPtr + dataSize, 0));
|
|
215
|
+
} else if (type instanceof JSON.Obj) {
|
|
216
|
+
// @ts-ignore
|
|
217
|
+
return inline.always(deserializeObject(dataPtr, dataPtr + dataSize, 0));
|
|
218
|
+
} else if (type instanceof JSON.Box) {
|
|
219
|
+
// @ts-ignore
|
|
220
|
+
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
|
|
221
|
+
} else {
|
|
222
|
+
throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
|
|
223
|
+
}
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
|
|
@@ -546,22 +547,22 @@ export namespace JSON {
|
|
|
546
547
|
// @ts-ignore: Supplied by transform
|
|
547
548
|
} else if (isDefined(src.__SERIALIZE)) {
|
|
548
549
|
// @ts-ignore
|
|
549
|
-
serializeStruct(changetype<nonnull<T>>(src));
|
|
550
|
+
inline.always(serializeStruct(changetype<nonnull<T>>(src)));
|
|
550
551
|
} else if (src instanceof Date) {
|
|
551
552
|
// @ts-ignore
|
|
552
|
-
serializeDate(changetype<nonnull<T>>(src));
|
|
553
|
+
inline.always(serializeDate(changetype<nonnull<T>>(src)));
|
|
553
554
|
} else if (src instanceof Array) {
|
|
554
555
|
// @ts-ignore
|
|
555
|
-
serializeArray(changetype<nonnull<T>>(src));
|
|
556
|
+
inline.always(serializeArray(changetype<nonnull<T>>(src)));
|
|
556
557
|
} else if (src instanceof Map) {
|
|
557
558
|
// @ts-ignore
|
|
558
|
-
serializeMap(changetype<nonnull<T>>(src));
|
|
559
|
+
inline.always(serializeMap(changetype<nonnull<T>>(src)));
|
|
559
560
|
} else if (src instanceof JSON.Raw) {
|
|
560
561
|
serializeRaw(src);
|
|
561
562
|
} else if (src instanceof JSON.Value) {
|
|
562
|
-
serializeArbitrary(src);
|
|
563
|
+
inline.always(serializeArbitrary(src));
|
|
563
564
|
} else if (src instanceof JSON.Obj) {
|
|
564
|
-
serializeObject(src);
|
|
565
|
+
inline.always(serializeObject(src));
|
|
565
566
|
} else if (src instanceof JSON.Box) {
|
|
566
567
|
__serialize(src.value);
|
|
567
568
|
} else {
|
|
@@ -581,8 +582,11 @@ export namespace JSON {
|
|
|
581
582
|
// @ts-ignore: type
|
|
582
583
|
return deserializeString(srcStart, srcEnd, dst);
|
|
583
584
|
} else if (isArray<T>()) {
|
|
585
|
+
// @ts-ignore: type
|
|
586
|
+
return inline.always(deserializeArray<T>(srcStart, srcEnd, dst));
|
|
587
|
+
} else if (isNullable<T>() && srcEnd - srcStart == 8 && load<u64>(srcStart) == 30399761348886638) {
|
|
584
588
|
// @ts-ignore
|
|
585
|
-
return
|
|
589
|
+
return null;
|
|
586
590
|
} else {
|
|
587
591
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
588
592
|
// @ts-ignore: Defined by transform
|
|
@@ -594,10 +598,10 @@ export namespace JSON {
|
|
|
594
598
|
return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(srcStart, srcEnd));
|
|
595
599
|
// @ts-ignore: Defined by transform
|
|
596
600
|
} else if (isDefined(type.__DESERIALIZE)) {
|
|
597
|
-
return deserializeStruct<T>(srcStart, srcEnd, dst);
|
|
601
|
+
return inline.always(deserializeStruct<T>(srcStart, srcEnd, dst));
|
|
598
602
|
} else if (type instanceof Map) {
|
|
599
603
|
// @ts-ignore: type
|
|
600
|
-
return deserializeMap<T>(srcStart, srcEnd, dst);
|
|
604
|
+
return inline.always(deserializeMap<T>(srcStart, srcEnd, dst));
|
|
601
605
|
} else if (type instanceof Date) {
|
|
602
606
|
// @ts-ignore: type
|
|
603
607
|
return deserializeDate(srcStart, srcEnd);
|
|
@@ -606,7 +610,7 @@ export namespace JSON {
|
|
|
606
610
|
return deserializeRaw(srcStart, srcEnd);
|
|
607
611
|
} else if (type instanceof JSON.Value) {
|
|
608
612
|
// @ts-ignore: type
|
|
609
|
-
return deserializeArbitrary(srcStart, srcEnd, 0);
|
|
613
|
+
return inline.always(deserializeArbitrary(srcStart, srcEnd, 0));
|
|
610
614
|
} else if (type instanceof JSON.Box) {
|
|
611
615
|
// @ts-ignore: type
|
|
612
616
|
return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));
|
|
@@ -620,12 +624,15 @@ export namespace JSON {
|
|
|
620
624
|
@inline function parseBox<T>(data: string, ty: T): T {
|
|
621
625
|
return JSON.parse<T>(data);
|
|
622
626
|
}
|
|
623
|
-
|
|
624
|
-
function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
|
|
627
|
+
// @ts-ignore: inline
|
|
628
|
+
@inline function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
|
|
625
629
|
return JSON.__deserialize<T>(srcStart, srcEnd, dst);
|
|
626
630
|
}
|
|
627
631
|
|
|
628
|
-
|
|
629
|
-
export function
|
|
632
|
+
// @ts-ignore: inline
|
|
633
|
+
@inline export function toRaw(data: string): JSON.Raw { return new JSON.Raw(data) }
|
|
634
|
+
// @ts-ignore: inline
|
|
635
|
+
@inline export function fromRaw(data: JSON.Raw): string { return data.data }
|
|
630
636
|
|
|
631
|
-
|
|
637
|
+
// @ts-ignore: inline
|
|
638
|
+
@inline export function toBox<T>(data: T): JSON.Box<T> { return new JSON.Box<T>(data) }
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { bs } from "../../../lib/as-bs";
|
|
2
2
|
import { dtoa_buffered } from "util/number";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// @ts-ignore: inline
|
|
5
|
+
@inline export function serializeFloat<T extends number>(data: T): void {
|
|
5
6
|
bs.ensureSize(64);
|
|
6
7
|
bs.offset += dtoa_buffered(bs.offset, data) << 1;
|
|
7
8
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { bs } from "../../../lib/as-bs";
|
|
2
2
|
import { itoa_buffered } from "util/number";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// @ts-ignore: inline
|
|
5
|
+
@inline export function serializeInteger<T extends number>(data: T): void {
|
|
5
6
|
bs.ensureSize(sizeof<T>() << 3);
|
|
6
7
|
const bytesWritten = itoa_buffered(bs.offset, data) << 1;
|
|
7
8
|
bs.offset += bytesWritten;
|
|
@@ -7,7 +7,8 @@ import { bytes } from "../../util";
|
|
|
7
7
|
* @param data data to serialize
|
|
8
8
|
* @returns void
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
// @ts-ignore: inline
|
|
11
|
+
@inline export function serializeRaw(data: JSON.Raw): void {
|
|
11
12
|
const dataSize = bytes(data.data);
|
|
12
13
|
bs.proposeSize(dataSize);
|
|
13
14
|
memory.copy(changetype<usize>(bs.offset), changetype<usize>(data.data), dataSize);
|
|
@@ -9,7 +9,8 @@ import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
|
9
9
|
* @param src string
|
|
10
10
|
* @returns void
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
// @ts-ignore: inline
|
|
13
|
+
@inline export function serializeString(src: string): void {
|
|
13
14
|
const srcSize = bytes(src);
|
|
14
15
|
bs.proposeSize(srcSize + 4);
|
|
15
16
|
let srcPtr = changetype<usize>(src);
|
package/assembly/test.ts
CHANGED
|
@@ -137,4 +137,15 @@ console.log("a11: " + JSON.stringify(a11));
|
|
|
137
137
|
|
|
138
138
|
const a12 = JSON.parse<InnerObj<ObjWithBracketString>>('{"obj":{"data":"hello} world"}}');
|
|
139
139
|
|
|
140
|
-
console.log("a12: " + JSON.stringify(a12))
|
|
140
|
+
console.log("a12: " + JSON.stringify(a12))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@json
|
|
144
|
+
class NullableObj {
|
|
145
|
+
bar: Bar | null = null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@json
|
|
149
|
+
class Bar {
|
|
150
|
+
value: string = "";
|
|
151
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { bench } from "./lib/bench";
|
|
2
|
+
|
|
3
|
+
const v1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
4
|
+
const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
|
|
5
|
+
|
|
6
|
+
bench(
|
|
7
|
+
"Serialize Alphabet",
|
|
8
|
+
() => {
|
|
9
|
+
JSON.stringify(v1);
|
|
10
|
+
},
|
|
11
|
+
64_000_00,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
bench(
|
|
15
|
+
"Deserialize Alphabet",
|
|
16
|
+
() => {
|
|
17
|
+
JSON.parse(v2);
|
|
18
|
+
},
|
|
19
|
+
64_000_00,
|
|
20
|
+
);
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { bench } from "./lib/bench";
|
|
2
|
+
|
|
3
|
+
class Vec3 {
|
|
4
|
+
public x!: number;
|
|
5
|
+
public y!: number;
|
|
6
|
+
public z!: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class LargeJSON {
|
|
10
|
+
public id!: number;
|
|
11
|
+
public name!: string;
|
|
12
|
+
public age!: number;
|
|
13
|
+
public email!: string;
|
|
14
|
+
public street!: string;
|
|
15
|
+
public city!: string;
|
|
16
|
+
public state!: string;
|
|
17
|
+
public zip!: string;
|
|
18
|
+
public tags!: string[];
|
|
19
|
+
public theme!: string;
|
|
20
|
+
public notifications!: boolean;
|
|
21
|
+
public language!: string;
|
|
22
|
+
public movement!: Vec3[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const v1: LargeJSON = {
|
|
26
|
+
id: 2,
|
|
27
|
+
name: "Medium Object",
|
|
28
|
+
age: 18,
|
|
29
|
+
email: "me@jairus.dev",
|
|
30
|
+
street: "I don't want to say my street",
|
|
31
|
+
city: "I don't want to say this either",
|
|
32
|
+
state: "It really depends",
|
|
33
|
+
zip: "I forget what it is",
|
|
34
|
+
tags: ["me", "dogs", "mountains", "bar", "foo"],
|
|
35
|
+
theme: "Hyper Term Black",
|
|
36
|
+
notifications: true,
|
|
37
|
+
language: "en-US",
|
|
38
|
+
movement: [
|
|
39
|
+
{ x: 1, y: 2, z: 3 },
|
|
40
|
+
{ x: 1, y: 2, z: 3 },
|
|
41
|
+
{ x: 1, y: 2, z: 3 },
|
|
42
|
+
{ x: 1, y: 2, z: 3 },
|
|
43
|
+
{ x: 1, y: 2, z: 3 },
|
|
44
|
+
{ x: 1, y: 2, z: 3 },
|
|
45
|
+
{ x: 1, y: 2, z: 3 },
|
|
46
|
+
{ x: 1, y: 2, z: 3 },
|
|
47
|
+
{ x: 1, y: 2, z: 3 },
|
|
48
|
+
{ x: 1, y: 2, z: 3 },
|
|
49
|
+
{ x: 1, y: 2, z: 3 },
|
|
50
|
+
{ x: 1, y: 2, z: 3 },
|
|
51
|
+
{ x: 1, y: 2, z: 3 },
|
|
52
|
+
{ x: 1, y: 2, z: 3 },
|
|
53
|
+
{ x: 1, y: 2, z: 3 },
|
|
54
|
+
{ x: 1, y: 2, z: 3 },
|
|
55
|
+
{ x: 1, y: 2, z: 3 },
|
|
56
|
+
{ x: 1, y: 2, z: 3 },
|
|
57
|
+
{ x: 1, y: 2, z: 3 },
|
|
58
|
+
{ x: 1, y: 2, z: 3 },
|
|
59
|
+
{ x: 1, y: 2, z: 3 },
|
|
60
|
+
{ x: 1, y: 2, z: 3 },
|
|
61
|
+
{ x: 1, y: 2, z: 3 },
|
|
62
|
+
{ x: 1, y: 2, z: 3 },
|
|
63
|
+
{ x: 1, y: 2, z: 3 },
|
|
64
|
+
{ x: 1, y: 2, z: 3 },
|
|
65
|
+
{ x: 1, y: 2, z: 3 },
|
|
66
|
+
{ x: 1, y: 2, z: 3 },
|
|
67
|
+
{ x: 1, y: 2, z: 3 },
|
|
68
|
+
{ x: 1, y: 2, z: 3 },
|
|
69
|
+
{ x: 1, y: 2, z: 3 },
|
|
70
|
+
{ x: 1, y: 2, z: 3 },
|
|
71
|
+
{ x: 1, y: 2, z: 3 },
|
|
72
|
+
{ x: 1, y: 2, z: 3 },
|
|
73
|
+
{ x: 1, y: 2, z: 3 },
|
|
74
|
+
{ x: 1, y: 2, z: 3 },
|
|
75
|
+
{ x: 1, y: 2, z: 3 },
|
|
76
|
+
{ x: 1, y: 2, z: 3 },
|
|
77
|
+
{ x: 1, y: 2, z: 3 },
|
|
78
|
+
{ x: 1, y: 2, z: 3 },
|
|
79
|
+
{ x: 1, y: 2, z: 3 },
|
|
80
|
+
{ x: 1, y: 2, z: 3 },
|
|
81
|
+
{ x: 1, y: 2, z: 3 },
|
|
82
|
+
{ x: 1, y: 2, z: 3 },
|
|
83
|
+
{ x: 1, y: 2, z: 3 },
|
|
84
|
+
{ x: 1, y: 2, z: 3 },
|
|
85
|
+
{ x: 1, y: 2, z: 3 },
|
|
86
|
+
{ x: 1, y: 2, z: 3 },
|
|
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
|
+
],
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
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}]}`;
|
|
111
|
+
|
|
112
|
+
bench(
|
|
113
|
+
"Serialize Medium Object",
|
|
114
|
+
() => {
|
|
115
|
+
JSON.stringify(v1);
|
|
116
|
+
},
|
|
117
|
+
3_000_00,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
bench(
|
|
121
|
+
"Deserialize Medium Object",
|
|
122
|
+
() => {
|
|
123
|
+
JSON.parse(v2);
|
|
124
|
+
},
|
|
125
|
+
3_000_00,
|
|
126
|
+
);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { bench } from "./lib/bench";
|
|
2
|
+
|
|
3
|
+
class MediumJSON {
|
|
4
|
+
public id!: number;
|
|
5
|
+
public name!: string;
|
|
6
|
+
public age!: number;
|
|
7
|
+
public email!: string;
|
|
8
|
+
public street!: string;
|
|
9
|
+
public city!: string;
|
|
10
|
+
public state!: string;
|
|
11
|
+
public zip!: string;
|
|
12
|
+
public tags!: string[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const v1: MediumJSON = {
|
|
16
|
+
id: 2,
|
|
17
|
+
name: "Medium Object",
|
|
18
|
+
age: 18,
|
|
19
|
+
email: "me@jairus.dev",
|
|
20
|
+
street: "I don't want to say my street",
|
|
21
|
+
city: "I don't want to say this either",
|
|
22
|
+
state: "It really depends",
|
|
23
|
+
zip: "I forget what it is",
|
|
24
|
+
tags: ["me", "dogs", "mountains", "bar", "foo"],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
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"]}`;
|
|
28
|
+
|
|
29
|
+
bench(
|
|
30
|
+
"Serialize Medium Object",
|
|
31
|
+
() => {
|
|
32
|
+
JSON.stringify(v1);
|
|
33
|
+
},
|
|
34
|
+
8_000_00,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
bench(
|
|
38
|
+
"Deserialize Medium Object",
|
|
39
|
+
() => {
|
|
40
|
+
JSON.parse(v2);
|
|
41
|
+
},
|
|
42
|
+
8_000_00,
|
|
43
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { bench } from "./lib/bench";
|
|
2
|
+
|
|
3
|
+
class SmallJSON {
|
|
4
|
+
public id!: number;
|
|
5
|
+
public name!: string;
|
|
6
|
+
public active!: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const v1: SmallJSON = {
|
|
10
|
+
id: 1,
|
|
11
|
+
name: "Small Object",
|
|
12
|
+
active: true,
|
|
13
|
+
};
|
|
14
|
+
const v2 = '{"id":1,"name":"Small Object","active":true}';
|
|
15
|
+
|
|
16
|
+
bench(
|
|
17
|
+
"Serialize Small Object",
|
|
18
|
+
() => {
|
|
19
|
+
JSON.stringify(v1);
|
|
20
|
+
},
|
|
21
|
+
16_000_00,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
bench(
|
|
25
|
+
"Deserialize Small Object",
|
|
26
|
+
() => {
|
|
27
|
+
JSON.parse(v2);
|
|
28
|
+
},
|
|
29
|
+
16_000_00,
|
|
30
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { bench } from "./lib/bench";
|
|
2
|
+
|
|
3
|
+
class Vec3 {
|
|
4
|
+
public x!: number;
|
|
5
|
+
public y!: number;
|
|
6
|
+
public z!: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const v1: Vec3 = { x: 1, y: 2, z: 3 };
|
|
10
|
+
const v2 = '{"x":1,"y":2,"z":3}';
|
|
11
|
+
|
|
12
|
+
bench(
|
|
13
|
+
"Serialize Vec3",
|
|
14
|
+
() => {
|
|
15
|
+
JSON.stringify(v1);
|
|
16
|
+
},
|
|
17
|
+
16_000_00,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
bench(
|
|
21
|
+
"Deserialize Vec3",
|
|
22
|
+
() => {
|
|
23
|
+
JSON.parse(v2);
|
|
24
|
+
},
|
|
25
|
+
16_000_00,
|
|
26
|
+
);
|
package/package.json
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"author": "Jairus Tanaka",
|
|
5
|
+
"description": "The only JSON library you'll need for AssemblyScript. SIMD enabled",
|
|
6
|
+
"types": "assembly/index.ts",
|
|
7
|
+
"main": "transform/lib/index.js",
|
|
8
|
+
"homepage": "https://github.com/JairusSW/json-as#readme",
|
|
9
|
+
"license": "MIT",
|
|
5
10
|
"repository": {
|
|
6
11
|
"type": "git",
|
|
7
12
|
"url": "git+https://github.com/JairusSW/json-as.git"
|
|
8
13
|
},
|
|
9
|
-
"
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/JairusSW/json-as/issues"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "bash ./run-tests.sh",
|
|
19
|
+
"bench:as": "bash ./run-bench.as.sh",
|
|
20
|
+
"bench:js": "bash ./run-bench.js.sh",
|
|
21
|
+
"build:time": "time npx asc ./assembly/__benches__/abc.bench.ts --transform ./transform -o ./build/abc.bench.wasm --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub --enable simd --enable bulk-memory",
|
|
22
|
+
"build:test": "rm -rf ./build/ && JSON_DEBUG=true asc --lib ./lib/ assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0",
|
|
23
|
+
"build:test:simd": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd",
|
|
24
|
+
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
25
|
+
"test:wasmer": "wasmer ./build/test.wasm",
|
|
26
|
+
"build:transform": "tsc -p ./transform",
|
|
27
|
+
"bench:wasmer": "wasmer ./build/bench.wasm --llvm",
|
|
28
|
+
"prettier": "prettier -w ."
|
|
29
|
+
},
|
|
10
30
|
"devDependencies": {
|
|
11
31
|
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
12
|
-
"@types/node": "^22.13.
|
|
13
|
-
"
|
|
14
|
-
"as-console": "^7.0.0",
|
|
15
|
-
"as-test": "^0.4.0-beta.3",
|
|
16
|
-
"assemblyscript": "^0.27.34",
|
|
32
|
+
"@types/node": "^22.13.10",
|
|
33
|
+
"assemblyscript": "^0.27.35",
|
|
17
34
|
"assemblyscript-prettier": "^3.0.1",
|
|
18
|
-
"prettier": "^3.5.
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"bugs": {
|
|
22
|
-
"url": "https://github.com/JairusSW/json-as/issues"
|
|
35
|
+
"prettier": "^3.5.3",
|
|
36
|
+
"tsx": "^4.19.3",
|
|
37
|
+
"typescript": "^5.8.2"
|
|
23
38
|
},
|
|
24
39
|
"contributors": [
|
|
25
40
|
"DogWhich",
|
|
@@ -31,8 +46,6 @@
|
|
|
31
46
|
"Matt Johnson-Pint",
|
|
32
47
|
"Tomáš Hromada"
|
|
33
48
|
],
|
|
34
|
-
"description": "The only JSON library you'll need for AssemblyScript. SIMD enabled",
|
|
35
|
-
"homepage": "https://github.com/JairusSW/json-as#readme",
|
|
36
49
|
"keywords": [
|
|
37
50
|
"assemblyscript",
|
|
38
51
|
"json",
|
|
@@ -48,24 +61,8 @@
|
|
|
48
61
|
"fast",
|
|
49
62
|
"algorithm"
|
|
50
63
|
],
|
|
51
|
-
"license": "MIT",
|
|
52
|
-
"overrides": {
|
|
53
|
-
"assemblyscript": "$assemblyscript"
|
|
54
|
-
},
|
|
55
64
|
"publishConfig": {
|
|
56
65
|
"@JairusSW:registry": "https://npm.pkg.github.com"
|
|
57
66
|
},
|
|
58
|
-
"
|
|
59
|
-
"test": "bash ./run-tests.sh",
|
|
60
|
-
"build:bench": "rm -rf ./build/ && JSON_DEBUG=true asc --lib ./lib/ assembly/__benches__/string.bench.ts -o ./build/bench.wasm --textFile ./build/bench.wat --transform ./transform --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub --enable simd --enable bulk-memory",
|
|
61
|
-
"build:test": "rm -rf ./build/ && JSON_DEBUG=true asc --lib ./lib/ assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0",
|
|
62
|
-
"build:test:simd": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd",
|
|
63
|
-
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
64
|
-
"test:wasmer": "wasmer ./build/test.wasm",
|
|
65
|
-
"build:transform": "tsc -p ./transform",
|
|
66
|
-
"bench:wasmer": "wasmer ./build/bench.wasm --llvm",
|
|
67
|
-
"prettier": "prettier -w ."
|
|
68
|
-
},
|
|
69
|
-
"type": "module",
|
|
70
|
-
"types": "assembly/index.ts"
|
|
67
|
+
"type": "module"
|
|
71
68
|
}
|
package/run-bench.as.sh
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
mkdir -p ./build
|
|
4
|
+
|
|
5
|
+
for file in ./assembly/__benches__/*.bench.ts; do
|
|
6
|
+
filename=$(basename -- "$file")
|
|
7
|
+
output="./build/${filename%.ts}.wasm"
|
|
8
|
+
|
|
9
|
+
start_time=$(date +%s%3N)
|
|
10
|
+
npx asc "$file" --transform ./transform -o "$output" --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub --enable simd --enable bulk-memory || { echo "Build failed"; exit 1; }
|
|
11
|
+
end_time=$(date +%s%3N)
|
|
12
|
+
|
|
13
|
+
build_time=$((end_time - start_time))
|
|
14
|
+
|
|
15
|
+
if [ "$build_time" -ge 60000 ]; then
|
|
16
|
+
formatted_time="$(bc <<< "scale=2; $build_time/60000")m"
|
|
17
|
+
elif [ "$build_time" -ge 1000 ]; then
|
|
18
|
+
formatted_time="$(bc <<< "scale=2; $build_time/1000")s"
|
|
19
|
+
else
|
|
20
|
+
formatted_time="${build_time}ms"
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
echo -e "$filename (built in $formatted_time)\n"
|
|
24
|
+
wasmer "$output" --llvm || { echo "Benchmarked failed."; exit 1; }
|
|
25
|
+
done
|
|
26
|
+
|
|
27
|
+
echo "Finished benchmarks."
|
package/run-bench.js.sh
ADDED