json-as 1.1.25 → 1.1.27
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 +64 -0
- package/.prettierrc.json +1 -0
- package/CHANGELOG.md +4 -0
- package/README.md +40 -63
- 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 +128 -0
- package/assembly/index.ts +6 -2
- package/assembly/serialize/swar/number.ts +0 -0
- package/assembly/serialize/swar/string.ts +72 -70
- package/assembly/test.tmp.ts +5 -9
- package/assembly/test.ts +3 -6
- 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/data/chart01.svg +258 -0
- package/data/chart02.svg +246 -0
- package/data/chart03.svg +193 -0
- package/data/chart05.svg +142 -0
- package/dump.txt +41590 -0
- package/package.json +4 -2
- 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/{bench → ci/bench}/lib/bench.ts +0 -0
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
import { JSON } from "../..";
|
|
2
|
+
// @ts-ignore: decorator allowed
|
|
3
|
+
@external("env", "writeFile")
|
|
4
|
+
declare function writeFile(fileName: string, data: string): void;
|
|
5
|
+
|
|
6
|
+
@json
|
|
7
|
+
class BenchResult {
|
|
8
|
+
language: string = "assemblyscript";
|
|
9
|
+
description!: string;
|
|
10
|
+
elapsed!: f64;
|
|
11
|
+
bytes!: u64;
|
|
12
|
+
operations!: u64;
|
|
13
|
+
features!: string[];
|
|
14
|
+
mbps!: f64;
|
|
15
|
+
gbps!: f64;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let result: BenchResult | null = null;
|
|
1
19
|
export function bench(description: string, routine: () => void, ops: u64 = 1_000_000, bytesPerOp: u64 = 0): void {
|
|
2
20
|
console.log(" - Benchmarking " + description);
|
|
3
21
|
|
|
@@ -20,15 +38,34 @@ export function bench(description: string, routine: () => void, ops: u64 = 1_000
|
|
|
20
38
|
|
|
21
39
|
let log = ` Completed benchmark in ${formatNumber(u64(Math.round(elapsed)))}ms at ${formatNumber(u64(Math.round(opsPerSecond)))} ops/s`;
|
|
22
40
|
|
|
41
|
+
let mbPerSec: f64 = 0;
|
|
23
42
|
if (bytesPerOp > 0) {
|
|
24
43
|
const totalBytes = bytesPerOp * ops;
|
|
25
|
-
|
|
44
|
+
mbPerSec = f64(totalBytes) / (elapsed / 1000) / (1000 * 1000);
|
|
26
45
|
log += ` @ ${formatNumber(u64(Math.round(mbPerSec)))}MB/s`;
|
|
27
46
|
}
|
|
28
47
|
|
|
48
|
+
const features: string[] = [];
|
|
49
|
+
if (ASC_FEATURE_SIMD) features.push("simd");
|
|
50
|
+
|
|
51
|
+
result = {
|
|
52
|
+
language: "assemblycript",
|
|
53
|
+
description,
|
|
54
|
+
elapsed,
|
|
55
|
+
bytes: bytesPerOp,
|
|
56
|
+
operations: ops,
|
|
57
|
+
features,
|
|
58
|
+
mbps: mbPerSec,
|
|
59
|
+
gbps: mbPerSec / 1000
|
|
60
|
+
}
|
|
61
|
+
|
|
29
62
|
console.log(log + "\n");
|
|
30
63
|
}
|
|
31
64
|
|
|
65
|
+
export function dumpToFile(suite: string, type: string): void {
|
|
66
|
+
writeFile("./build/logs/as/"+ (ASC_FEATURE_SIMD ? "simd/" : "swar/") + suite+"."+type+".as.json", JSON.stringify(result));
|
|
67
|
+
}
|
|
68
|
+
|
|
32
69
|
function formatNumber(n: u64): string {
|
|
33
70
|
let str = n.toString();
|
|
34
71
|
let len = str.length;
|
|
@@ -40,3 +77,9 @@ function formatNumber(n: u64): string {
|
|
|
40
77
|
}
|
|
41
78
|
return result;
|
|
42
79
|
}
|
|
80
|
+
|
|
81
|
+
const blackBoxArea = memory.data(64);
|
|
82
|
+
export function blackbox<T>(value: T): T {
|
|
83
|
+
store<T>(blackBoxArea, value);
|
|
84
|
+
return load<T>(blackBoxArea);
|
|
85
|
+
}
|
|
@@ -1,49 +1,128 @@
|
|
|
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
|
+
@json
|
|
6
|
+
class UserPreferences {
|
|
7
|
+
theme!: string;
|
|
8
|
+
notifications!: boolean;
|
|
9
|
+
language!: string;
|
|
10
|
+
timezone!: string;
|
|
11
|
+
privacy_level!: string;
|
|
12
|
+
two_factor_enabled!: boolean;
|
|
13
|
+
}
|
|
5
14
|
|
|
6
15
|
@json
|
|
7
|
-
class
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
public email!: string;
|
|
12
|
-
public street!: string;
|
|
13
|
-
public city!: string;
|
|
14
|
-
public state!: string;
|
|
15
|
-
public zip!: string;
|
|
16
|
-
public tags!: string[];
|
|
16
|
+
class RecentActivity {
|
|
17
|
+
action!: string;
|
|
18
|
+
timestamp!: string;
|
|
19
|
+
target!: string;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
@json
|
|
23
|
+
class MediumAPIResponse {
|
|
24
|
+
id!: i32;
|
|
25
|
+
username!: string;
|
|
26
|
+
full_name!: string;
|
|
27
|
+
email!: string;
|
|
28
|
+
avatar_url!: string;
|
|
29
|
+
bio!: string;
|
|
30
|
+
website!: string;
|
|
31
|
+
location!: string;
|
|
32
|
+
joined_at!: string;
|
|
33
|
+
is_verified!: boolean;
|
|
34
|
+
is_premium!: boolean;
|
|
35
|
+
follower_count!: i32;
|
|
36
|
+
following_count!: i32;
|
|
37
|
+
|
|
38
|
+
preferences!: UserPreferences;
|
|
39
|
+
tags!: string[];
|
|
40
|
+
|
|
41
|
+
recent_activity!: RecentActivity[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const v1 = new MediumAPIResponse();
|
|
45
|
+
const prefs = new UserPreferences();
|
|
46
|
+
|
|
47
|
+
prefs.theme = "dark";
|
|
48
|
+
prefs.notifications = true;
|
|
49
|
+
prefs.language = "en-US";
|
|
50
|
+
prefs.timezone = "America/Los_Angeles";
|
|
51
|
+
prefs.privacy_level = "friends_only";
|
|
52
|
+
prefs.two_factor_enabled = false;
|
|
53
|
+
|
|
54
|
+
v1.id = 42;
|
|
55
|
+
v1.username = "jairus";
|
|
56
|
+
v1.full_name = "Jairus Tanaka";
|
|
57
|
+
v1.email = "me@jairus.dev";
|
|
58
|
+
v1.avatar_url = "https://avatars.githubusercontent.com/u/123456?v=4";
|
|
59
|
+
v1.bio = "I like compilers, elegant algorithms, bare metal, simd, and wasm.";
|
|
60
|
+
v1.website = "https://jairus.dev/";
|
|
61
|
+
v1.location = "Seattle, WA";
|
|
62
|
+
v1.joined_at = "2020-01-15T08:30:00Z";
|
|
63
|
+
v1.is_verified = true;
|
|
64
|
+
v1.is_premium = true;
|
|
65
|
+
v1.follower_count = 61;
|
|
66
|
+
v1.following_count = 39;
|
|
67
|
+
|
|
68
|
+
v1.preferences = prefs;
|
|
69
|
+
|
|
70
|
+
v1.tags = ["typescript", "webassembly", "performance", "rust", "assemblyscript", "json"];
|
|
71
|
+
|
|
72
|
+
v1.recent_activity = new Array<RecentActivity>(5);
|
|
73
|
+
|
|
74
|
+
let act0 = new RecentActivity();
|
|
75
|
+
act0.action = "starred";
|
|
76
|
+
act0.timestamp = "2025-12-22T10:15:00Z";
|
|
77
|
+
act0.target = "assemblyscript/json-as";
|
|
78
|
+
v1.recent_activity[0] = act0;
|
|
79
|
+
|
|
80
|
+
let act1 = new RecentActivity();
|
|
81
|
+
act1.action = "commented";
|
|
82
|
+
act1.timestamp = "2025-12-22T09:42:00Z";
|
|
83
|
+
act1.target = "issue #142";
|
|
84
|
+
v1.recent_activity[1] = act1;
|
|
85
|
+
|
|
86
|
+
let act2 = new RecentActivity();
|
|
87
|
+
act2.action = "pushed";
|
|
88
|
+
act2.timestamp = "2025-12-21T23:58:00Z";
|
|
89
|
+
act2.target = "main branch";
|
|
90
|
+
v1.recent_activity[2] = act2;
|
|
91
|
+
|
|
92
|
+
let act3 = new RecentActivity();
|
|
93
|
+
act3.action = "forked";
|
|
94
|
+
act3.timestamp = "2025-12-21T18:20:00Z";
|
|
95
|
+
act3.target = "fast-json-wasm";
|
|
96
|
+
v1.recent_activity[3] = act3;
|
|
97
|
+
|
|
98
|
+
let act4 = new RecentActivity();
|
|
99
|
+
act4.action = "created";
|
|
100
|
+
act4.timestamp = "2025-12-21T14:10:00Z";
|
|
101
|
+
act4.target = "new benchmark suite";
|
|
102
|
+
v1.recent_activity[4] = act4;
|
|
30
103
|
|
|
31
|
-
const v2 =
|
|
104
|
+
const v2: string = JSON.stringify<MediumAPIResponse>(v1);
|
|
105
|
+
const byteLength: usize = v2.length << 1;
|
|
32
106
|
|
|
33
107
|
expect(JSON.stringify(v1)).toBe(v2);
|
|
108
|
+
expect(JSON.stringify(JSON.parse<MediumAPIResponse>(v2))).toBe(v2);
|
|
34
109
|
|
|
35
110
|
bench(
|
|
36
|
-
"Serialize Medium
|
|
111
|
+
"Serialize Medium API Response",
|
|
37
112
|
() => {
|
|
38
|
-
JSON.stringify(v1);
|
|
113
|
+
blackbox(inline.always(JSON.stringify<MediumAPIResponse>(v1)));
|
|
39
114
|
},
|
|
40
|
-
|
|
115
|
+
500_000,
|
|
116
|
+
byteLength
|
|
41
117
|
);
|
|
118
|
+
dumpToFile("medium", "serialize")
|
|
42
119
|
|
|
43
120
|
bench(
|
|
44
|
-
"Deserialize Medium
|
|
121
|
+
"Deserialize Medium API Response",
|
|
45
122
|
() => {
|
|
46
|
-
JSON.parse<
|
|
123
|
+
blackbox(inline.always(JSON.parse<MediumAPIResponse>(v2)));
|
|
47
124
|
},
|
|
48
|
-
|
|
125
|
+
500_000,
|
|
126
|
+
byteLength
|
|
49
127
|
);
|
|
128
|
+
dumpToFile("medium", "deserialize")
|
|
@@ -1,36 +1,46 @@
|
|
|
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
|
-
class
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
class SessionStatusResponse {
|
|
7
|
+
authenticated!: boolean;
|
|
8
|
+
user_id!: i32;
|
|
9
|
+
username!: string;
|
|
10
|
+
role!: string;
|
|
11
|
+
expires_at!: string;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
const v1
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const v1 = new SessionStatusResponse();
|
|
15
|
+
|
|
16
|
+
v1.authenticated = true;
|
|
17
|
+
v1.user_id = 8472;
|
|
18
|
+
v1.username = "jairus";
|
|
19
|
+
v1.role = "admin";
|
|
20
|
+
v1.expires_at = "2025-12-23T04:30:00Z";
|
|
21
|
+
|
|
22
|
+
const v2: string = JSON.stringify<SessionStatusResponse>(v1);
|
|
23
|
+
const byteLength: usize = v2.length << 1;
|
|
19
24
|
|
|
20
25
|
expect(JSON.stringify(v1)).toBe(v2);
|
|
26
|
+
expect(JSON.stringify(JSON.parse<SessionStatusResponse>(v2))).toBe(v2);
|
|
21
27
|
|
|
22
28
|
bench(
|
|
23
|
-
"Serialize Small
|
|
29
|
+
"Serialize Small API Response",
|
|
24
30
|
() => {
|
|
25
|
-
JSON.stringify(v1);
|
|
31
|
+
blackbox(inline.always(JSON.stringify<SessionStatusResponse>(v1)));
|
|
26
32
|
},
|
|
27
|
-
|
|
33
|
+
5_000_000,
|
|
34
|
+
byteLength
|
|
28
35
|
);
|
|
36
|
+
dumpToFile("small", "serialize")
|
|
29
37
|
|
|
30
38
|
bench(
|
|
31
|
-
"Deserialize Small
|
|
39
|
+
"Deserialize Small API Response",
|
|
32
40
|
() => {
|
|
33
|
-
JSON.parse<
|
|
41
|
+
blackbox(inline.always(JSON.parse<SessionStatusResponse>(v2)));
|
|
34
42
|
},
|
|
35
|
-
|
|
43
|
+
5_000_000,
|
|
44
|
+
byteLength
|
|
36
45
|
);
|
|
46
|
+
dumpToFile("small", "deserialize")
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { bs } from "../../lib/as-bs";
|
|
3
|
+
import { expect } from "../__tests__/lib";
|
|
4
|
+
import { bytes } from "../util";
|
|
5
|
+
import { bench, blackbox, dumpToFile } from "./lib/bench";
|
|
6
|
+
|
|
7
|
+
// @json // 256b
|
|
8
|
+
// class ObjSmall {
|
|
9
|
+
// lorum: i32 = I32.MAX_VALUE;
|
|
10
|
+
// ipsum: boolean = true;
|
|
11
|
+
// dolor: Array<i32> = [1];
|
|
12
|
+
// sit: string = "abcdefghijklmnopdasfqrstfuvwYZ1234567890`~!@#$%^&*()_+=-{}][\\|;\":'<>,./?";
|
|
13
|
+
// }
|
|
14
|
+
|
|
15
|
+
// @json // 512b
|
|
16
|
+
// class ObjMedium {
|
|
17
|
+
// lorum: u32 = U32.MAX_VALUE;
|
|
18
|
+
// ipsum: boolean = true;
|
|
19
|
+
// dolor: Array<i32> = [1,2,3,4,5];
|
|
20
|
+
// sit: string = "abcdefghijklmnopdasfqrstfuvwYZ1234567890`~!@#$%^&*()_+=-{}][\\|;\":'<>,./?";
|
|
21
|
+
// consectetur: i32 = 123456;
|
|
22
|
+
// adipiscing: boolean = false;
|
|
23
|
+
// elit: Array<i32> = [6,7,8,9,10];
|
|
24
|
+
// sed: f64 = F64.MAX_VALUE;
|
|
25
|
+
// eiusmod: string = "abcdYZ12345890./?";
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
@json // 1 KB
|
|
29
|
+
class ObjLarge {
|
|
30
|
+
lorum: u32 = U32.MAX_VALUE;
|
|
31
|
+
ipsum: boolean = true;
|
|
32
|
+
dolor: Array<i32> = [1,2,3,4,5];
|
|
33
|
+
sit: string = "abcdefghijklmnopdasfqrstfuvwYZ1234567890;~!@#$%^&*()_+=-{}][\\|;\":'<>,./?";
|
|
34
|
+
consectetur: i32 = 123456;
|
|
35
|
+
adipiscing: boolean = false;
|
|
36
|
+
elit: Array<i32> = [6,7,8,9,10];
|
|
37
|
+
sed: f64 = F64.MAX_VALUE;
|
|
38
|
+
eiusmod: string = "abcdYZ12345890./?abcdYZ12345890./?abcdYZ12340./?";
|
|
39
|
+
tempor: i32 = 999999;
|
|
40
|
+
incididunt: boolean = true;
|
|
41
|
+
ut: Array<i32> = [16,17,18,19,20];
|
|
42
|
+
labore: f64 = 3.1415926535;
|
|
43
|
+
et: string = "xyzXYZ09876!@#";
|
|
44
|
+
dolore: i32 = -123456;
|
|
45
|
+
magna: boolean = false;
|
|
46
|
+
aliqua: Array<i32> = [21,22,23,24,25];
|
|
47
|
+
argw: string = "abcdYZ12345890sdfw\"vie91kfESDFOK12i9i12dsf./?";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const obj = new ObjLarge();
|
|
51
|
+
|
|
52
|
+
const arrSmall = new Array<i32>(25_600).fill(0);
|
|
53
|
+
const arrMedium = new Array<i32>(128_000).fill(0);
|
|
54
|
+
const arrLarge = new Array<i32>(256_000).fill(0);
|
|
55
|
+
|
|
56
|
+
const strSmall = "a".repeat(100 * 1024);
|
|
57
|
+
const strMedium = "a".repeat(500 * 1024);
|
|
58
|
+
const strLarge = "a".repeat(1024 * 1024);
|
|
59
|
+
|
|
60
|
+
const arrSmallStr = JSON.stringify(arrSmall);
|
|
61
|
+
const arrMediumStr = JSON.stringify(arrMedium);
|
|
62
|
+
const arrLargeStr = JSON.stringify(arrLarge);
|
|
63
|
+
|
|
64
|
+
const strSmallStr = JSON.stringify(strSmall);
|
|
65
|
+
const strMediumStr = JSON.stringify(strMedium);
|
|
66
|
+
const strLargeStr = JSON.stringify(strLarge);
|
|
67
|
+
|
|
68
|
+
const objStr = JSON.stringify(obj); // `{"lorum":4294967295,"ipsum":true,"dolor":[1,2,3,4,5],"sit":"abcdefghijklmnopdasfqrstfuvwYZ1234567890;~!@#$%^&*()_+=-{}][\\\\|;\\":'<>,./?","consectetur":123456,"adipiscing":false,"elit":[6,7,8,9,10],"sed":1.7976931348623157e+308,"eiusmod":"abcdYZ12345890./?abcdYZ12345890./?abcdYZ12340./?","tempor":999999,"incididunt":true,"ut":[16,17,18,19,20],"labore":3.1415926535,"et":"xyzXYZ09876!@#","dolore":-123456,"magna":false,"aliqua":[21,22,23,24,25],"argw":"abcdYZ12345890sdfw\\"vie91kfESDFOK12i9i12dsf./?"}`;
|
|
69
|
+
const objStrEnd = changetype<usize>(objStr) + (objStr.length << 1);
|
|
70
|
+
|
|
71
|
+
console.log(objStr)
|
|
72
|
+
expect(JSON.stringify(obj)).toBe(objStr);
|
|
73
|
+
expect(JSON.stringify(JSON.parse<ObjLarge>(objStr))).toBe(objStr);
|
|
74
|
+
const ITER = 2_000_000;
|
|
75
|
+
|
|
76
|
+
/* --- OBJECTS --- */
|
|
77
|
+
bench("Serialize Small Object", () => { // 1kb
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
obj.__SERIALIZE(changetype<usize>(obj));
|
|
80
|
+
blackbox(bs.out<string>());
|
|
81
|
+
}, 250_0000, objStr.length << 1);
|
|
82
|
+
dumpToFile("small-obj", "serialize");
|
|
83
|
+
|
|
84
|
+
// bench("Deserialize Small Object", () => {
|
|
85
|
+
// blackbox(JSON.parse<typeof objSmall>(objSmallStr))
|
|
86
|
+
// }, ITER, objSmallStr.length << 1);
|
|
87
|
+
// dumpToFile("small-obj", "deserialize");
|
|
88
|
+
|
|
89
|
+
// bench("Serialize Medium Object", () => { // 500kb
|
|
90
|
+
// let ops = 500;
|
|
91
|
+
// while(ops > 0) {
|
|
92
|
+
// // @ts-ignore
|
|
93
|
+
// objLarge.__SERIALIZE(changetype<usize>(objLarge));
|
|
94
|
+
// ops--;
|
|
95
|
+
// }
|
|
96
|
+
// blackbox(bs.out<string>());
|
|
97
|
+
// }, 5_000, (objLargeStr.length << 1) * 500);
|
|
98
|
+
// dumpToFile("medium-obj", "serialize");
|
|
99
|
+
|
|
100
|
+
// bench("Serialize Large Object", () => { // 500kb
|
|
101
|
+
// let ops = 1000;
|
|
102
|
+
// while(ops > 0) {
|
|
103
|
+
// // @ts-ignore
|
|
104
|
+
// objLarge.__SERIALIZE(changetype<usize>(objLarge));
|
|
105
|
+
// ops--;
|
|
106
|
+
// }
|
|
107
|
+
// blackbox(bs.out<string>());
|
|
108
|
+
// }, 500, (objLargeStr.length << 1) * 1000);
|
|
109
|
+
// dumpToFile("large-obj", "serialize");
|
|
110
|
+
|
|
111
|
+
// bench("Deserialize Small Object", () => {
|
|
112
|
+
// // @ts-ignore
|
|
113
|
+
// objLarge.__DESERIALIZE<ObjLarge>(changetype<usize>(objLargeStr), objLargeStrEnd, changetype<ObjLarge>(__new(sizeof<ObjLarge>(), idof<ObjLarge>())));
|
|
114
|
+
// }, 250_000, objLargeStr.length << 1);
|
|
115
|
+
// dumpToFile("small-obj", "deserialize");
|
|
116
|
+
|
|
117
|
+
// bench("Deserialize Medium Object", () => {
|
|
118
|
+
// let ops = 500;
|
|
119
|
+
// while (ops > 0) {
|
|
120
|
+
// // @ts-ignore
|
|
121
|
+
// objLarge.__DESERIALIZE<ObjLarge>(changetype<usize>(objLargeStr), objLargeStrEnd, changetype<ObjLarge>(__new(sizeof<ObjLarge>(), idof<ObjLarge>())));
|
|
122
|
+
// ops--;
|
|
123
|
+
// }
|
|
124
|
+
// }, 5_000, (objLargeStr.length << 1) * 500);
|
|
125
|
+
// dumpToFile("medium-obj", "deserialize");
|
|
126
|
+
|
|
127
|
+
// bench("Deserialize Large Object", () => {
|
|
128
|
+
// let ops = 1000;
|
|
129
|
+
// while (ops > 0) {
|
|
130
|
+
// // @ts-ignore
|
|
131
|
+
// objLarge.__DESERIALIZE<ObjLarge>(changetype<usize>(objLargeStr), objLargeStrEnd, changetype<ObjLarge>(__new(sizeof<ObjLarge>(), idof<ObjLarge>())));
|
|
132
|
+
// ops--;
|
|
133
|
+
// }
|
|
134
|
+
// }, 500, (objLargeStr.length << 1)*1000);
|
|
135
|
+
// dumpToFile("large-obj", "deserialize");
|
|
136
|
+
|
|
137
|
+
// // bench("Deserialize Medium Object", () => blackbox(JSON.parse<typeof objMedium>(objMediumStr)), ITER, objMediumStr.length << 1);
|
|
138
|
+
// // dumpToFile("medium-obj", "deserialize");
|
|
139
|
+
// // bench("Deserialize Large Object", () => blackbox(JSON.parse<typeof objLarge>(objLargeStr)), ITER, objLargeStr.length << 1);
|
|
140
|
+
// // dumpToFile("large-obj", "deserialize");
|
|
141
|
+
|
|
142
|
+
// /* --- ARRAYS --- */
|
|
143
|
+
// bench("Serialize Small Array", () => blackbox(JSON.stringify(arrSmall)), ITER, arrSmallStr.length << 1);
|
|
144
|
+
// dumpToFile("small-arr", "serialize");
|
|
145
|
+
// bench("Deserialize Small Array", () => blackbox(JSON.parse<i32[]>(arrSmallStr)), ITER, arrSmallStr.length << 1);
|
|
146
|
+
// dumpToFile("small-arr", "deserialize");
|
|
147
|
+
|
|
148
|
+
// bench("Serialize Medium Array", () => blackbox(JSON.stringify(arrMedium)), ITER, arrMediumStr.length << 1);
|
|
149
|
+
// dumpToFile("medium-arr", "serialize");
|
|
150
|
+
// bench("Deserialize Medium Array", () => blackbox(JSON.parse<i32[]>(arrMediumStr)), ITER, arrMediumStr.length << 1);
|
|
151
|
+
// dumpToFile("medium-arr", "deserialize");
|
|
152
|
+
|
|
153
|
+
// bench("Serialize Large Array", () => blackbox(JSON.stringify(arrLarge)), ITER, arrLargeStr.length << 1);
|
|
154
|
+
// dumpToFile("large-arr", "serialize");
|
|
155
|
+
// bench("Deserialize Large Array", () => blackbox(JSON.parse<i32[]>(arrLargeStr)), ITER, arrLargeStr.length << 1);
|
|
156
|
+
// dumpToFile("large-arr", "deserialize");
|
|
157
|
+
|
|
158
|
+
// /* --- STRINGS --- */
|
|
159
|
+
// bench("Serialize Small String", () => blackbox(JSON.stringify(strSmall)), ITER, strSmallStr.length << 1);
|
|
160
|
+
// dumpToFile("small-str", "serialize");
|
|
161
|
+
// bench("Deserialize Small String", () => blackbox(JSON.parse<string>(strSmallStr)), ITER, strSmallStr.length << 1);
|
|
162
|
+
// dumpToFile("small-str", "deserialize");
|
|
163
|
+
|
|
164
|
+
// bench("Serialize Medium String", () => blackbox(JSON.stringify(strMedium)), ITER, strMediumStr.length << 1);
|
|
165
|
+
// dumpToFile("medium-str", "serialize");
|
|
166
|
+
// bench("Deserialize Medium String", () => blackbox(JSON.parse<string>(strMediumStr)), ITER, strMediumStr.length << 1);
|
|
167
|
+
// dumpToFile("medium-str", "deserialize");
|
|
168
|
+
|
|
169
|
+
// bench("Serialize Large String", () => blackbox(JSON.stringify(strLarge)), ITER, strLargeStr.length << 1);
|
|
170
|
+
// dumpToFile("large-str", "serialize");
|
|
171
|
+
// bench("Deserialize Large String", () => blackbox(JSON.parse<string>(strLargeStr)), ITER, strLargeStr.length << 1);
|
|
172
|
+
// dumpToFile("large-str", "deserialize");
|
|
@@ -1,6 +1,6 @@
|
|
|
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
|
|
|
6
6
|
@json
|
|
@@ -14,19 +14,24 @@ const v1: Vec3 = { x: 1, y: 2, z: 3 };
|
|
|
14
14
|
const v2 = '{"x":1,"y":2,"z":3}';
|
|
15
15
|
|
|
16
16
|
expect(JSON.stringify(v1)).toBe(v2);
|
|
17
|
+
expect(JSON.stringify(JSON.parse<Vec3>(v2))).toBe(v2);
|
|
17
18
|
|
|
18
19
|
bench(
|
|
19
20
|
"Serialize Vec3",
|
|
20
21
|
() => {
|
|
21
|
-
JSON.stringify(v1);
|
|
22
|
+
blackbox(inline.always(JSON.stringify(v1)));
|
|
22
23
|
},
|
|
23
24
|
128_000_00,
|
|
25
|
+
v2.length << 1
|
|
24
26
|
);
|
|
27
|
+
dumpToFile("vec3", "serialize")
|
|
25
28
|
|
|
26
29
|
bench(
|
|
27
30
|
"Deserialize Vec3",
|
|
28
31
|
() => {
|
|
29
|
-
JSON.parse<Vec3>(v2);
|
|
32
|
+
blackbox(inline.always(JSON.parse<Vec3>(v2)));
|
|
30
33
|
},
|
|
31
34
|
128_000_00,
|
|
35
|
+
v2.length << 1
|
|
32
36
|
);
|
|
37
|
+
dumpToFile("vec3", "deserialize")
|
|
@@ -11,6 +11,8 @@ describe("Should serialize strings", () => {
|
|
|
11
11
|
expect(JSON.stringify('string with colon : comma , brace [ ] bracket { } and quote " and other quote \\"')).toBe('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\\\\\""');
|
|
12
12
|
|
|
13
13
|
expect(JSON.stringify("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f")).toBe('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"');
|
|
14
|
+
|
|
15
|
+
expect(JSON.stringify("abcdYZ12345890sdfw\"vie91kfESDFOK12i9i12dsf./?")).toBe('"abcdYZ12345890sdfw\\"vie91kfESDFOK12i9i12dsf./?"');
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
describe("Should deserialize strings", () => {
|
|
@@ -23,4 +25,6 @@ describe("Should deserialize strings", () => {
|
|
|
23
25
|
expect(JSON.parse<string>('"\\"string with colon : comma , brace [ ] bracket { } and quote \\\\\\" and other quote \\\\\\\\\\"\\""')).toBe('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\\\""');
|
|
24
26
|
|
|
25
27
|
expect(JSON.parse<string>('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"')).toBe("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f");
|
|
28
|
+
|
|
29
|
+
expect(JSON.parse<string>('"abcdYZ12345890sdfw\\"vie91kfESDFOK12i9i12dsf./?"')).toBe("abcdYZ12345890sdfw\"vie91kfESDFOK12i9i12dsf./?");
|
|
26
30
|
});
|
|
@@ -5,11 +5,14 @@ import { deserializeFloat } from "./float";
|
|
|
5
5
|
import { deserializeString } from "./string";
|
|
6
6
|
import { deserializeObject } from "./object";
|
|
7
7
|
import { BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE } from "../../custom/chars";
|
|
8
|
+
import { bs } from "../../../lib/as-bs";
|
|
9
|
+
import { deserializeString_SWAR } from "../swar/string";
|
|
8
10
|
|
|
9
11
|
export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value {
|
|
10
12
|
const firstChar = load<u16>(srcStart);
|
|
11
|
-
if (firstChar == QUOTE)
|
|
12
|
-
|
|
13
|
+
if (firstChar == QUOTE) {
|
|
14
|
+
return JSON.Value.from(deserializeString(srcStart, srcEnd, 0));
|
|
15
|
+
} else if (firstChar == BRACE_LEFT) return JSON.Value.from(deserializeObject(srcStart, srcEnd, 0));
|
|
13
16
|
else if (firstChar - 48 <= 9 || firstChar == 45) return JSON.Value.from(deserializeFloat<f64>(srcStart, srcEnd));
|
|
14
17
|
else if (firstChar == BRACKET_LEFT) {
|
|
15
18
|
return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, 0));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
|
+
import { bs } from "../../../lib/as-bs";
|
|
2
3
|
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
|
|
3
4
|
import { isSpace } from "../../util";
|
|
4
5
|
import { ptrToStr } from "../../util/ptrToStr";
|
|
6
|
+
import { deserializeString_SWAR } from "../swar/string";
|
|
5
7
|
import { deserializeArbitrary } from "./arbitrary";
|
|
6
8
|
import { deserializeArray } from "./array";
|
|
7
9
|
import { deserializeBoolean } from "./bool";
|
|
@@ -52,7 +54,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
52
54
|
while (srcStart < srcEnd) {
|
|
53
55
|
const code = load<u16>(srcStart);
|
|
54
56
|
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
55
|
-
// console.log("Value (string):-" +
|
|
57
|
+
// console.log("Value (string):-" + deserializeString_SWAR(lastIndex, srcStart + 2, 0) + "-");
|
|
56
58
|
out.set(ptrToStr(keyStart, keyEnd), deserializeString(lastIndex, srcStart + 2, 0));
|
|
57
59
|
// while (isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
58
60
|
srcStart += 4;
|