json-as 0.5.42 → 0.5.51
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/README.md +29 -16
- package/assembly/__benches__/as-json.ts +30 -48
- package/assembly/__tests__/as-json.spec.ts +0 -9
- package/bench.js +67 -0
- package/package.json +3 -3
- package/transform/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,25 +93,38 @@ Fully supports:
|
|
|
93
93
|
|
|
94
94
|
## Performance
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
Here are some benchmarks I took with `tinybench` (JavaScript) and `astral` (AssemblyScript).
|
|
97
|
+
I took the benchmarks using the minimal runtime which doesn't call the Garbage Collector, so you may expect a 10% to 40% decrease from low to high throughput.
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
Tests are run on Ubuntu/WSL2 with a AMD Ryzen 9 CPU
|
|
99
100
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
101
|
+
JavaScript Results (TinyBench/NodeJS 19)
|
|
102
|
+
```
|
|
103
|
+
┌───────────────────────────┬─────────────┬────────────────────┬──────────┐
|
|
104
|
+
│ Task Name │ ops / sec │ Average Time(ns) │ Margin │
|
|
105
|
+
├───────────────────────────┼─────────────┼────────────────────┼──────────┤
|
|
106
|
+
│ 'Stringify Object (Vec3)' │ '817,816' │ 1222.76 │ '±3.55%' │
|
|
107
|
+
│ 'Parse Object (Vec3)' │ '726,115' │ 1377.19 │ '±3.21%' │
|
|
108
|
+
│ 'Stringify Number Array' │ '1,104,036' │ 905.77 │ '±6.48%' │
|
|
109
|
+
│ 'Parse Number Array' │ '1,114,053' │ 897.62 │ '±2.58%' │
|
|
110
|
+
│ 'Stringify String' │ '1,565,716' │ 638.69 │ '±2.04%' │
|
|
111
|
+
│ 'Parse String' │ '69,568' │ 14374.22 │ '±2.55%' │
|
|
112
|
+
└───────────────────────────┴─────────────┴────────────────────┴──────────┘
|
|
113
|
+
```
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
AssemblyScript Results (Runtime Minimal)
|
|
116
|
+
```
|
|
117
|
+
┌───────────────────────────┬─────────────┬────────────────────┬──────────┐
|
|
118
|
+
│ Task Name │ ops / sec │ Average Time(ns) │ Diff │
|
|
119
|
+
├───────────────────────────┼─────────────┼────────────────────┼──────────┤
|
|
120
|
+
│ 'Stringify Object (Vec3)' │ '2,091,000' │ 417.22 │ -805ns │
|
|
121
|
+
│ 'Parse Object (Vec3)' │ '1,780,000' │ 539.02 │ -838ns |
|
|
122
|
+
│ 'Stringify Number Array' │ '1,920,000' │ 445.43 │ -460ns │
|
|
123
|
+
│ 'Parse Number Array' │ '1,660,000' │ 597.17 │ -300ns │
|
|
124
|
+
│ 'Stringify String' │ '1,280,000' │ 736.27 │ +97ns │
|
|
125
|
+
│ 'Parse String' │ '4,230,000' │ 239.21 │ -14135ns │
|
|
126
|
+
└───────────────────────────┴─────────────┴────────────────────┴──────────┘
|
|
127
|
+
```
|
|
115
128
|
|
|
116
129
|
## Issues
|
|
117
130
|
|
|
@@ -3,6 +3,13 @@ import { backSlashCode, quoteCode } from "../src/chars";
|
|
|
3
3
|
import { atoi_fast, parseSciInteger, unsafeCharCodeAt } from "../src/util";
|
|
4
4
|
import { HASH } from "util/hash";
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
let last = 1;
|
|
8
|
+
let char = 0;
|
|
9
|
+
let inStr = false;
|
|
10
|
+
let key: string | null = null;
|
|
11
|
+
let pos = 0;
|
|
12
|
+
|
|
6
13
|
@json
|
|
7
14
|
class Vec3 {
|
|
8
15
|
x: i32;
|
|
@@ -12,20 +19,15 @@ class Vec3 {
|
|
|
12
19
|
data: string,
|
|
13
20
|
to: Vec3
|
|
14
21
|
): Vec3 {
|
|
15
|
-
let last = 1;
|
|
16
|
-
let char = 0;
|
|
17
|
-
let inStr = false;
|
|
18
|
-
let key: string | null = null;
|
|
19
|
-
let pos = 0;
|
|
20
22
|
for (; pos < data.length - 1; pos++) {
|
|
21
23
|
char = unsafeCharCodeAt(data, pos);
|
|
22
24
|
if (inStr === false && char === quoteCode) {
|
|
23
25
|
if (key != null) {
|
|
24
|
-
if (unsafeCharCodeAt(key
|
|
26
|
+
if (unsafeCharCodeAt(key!, 0) == 120) {
|
|
25
27
|
to.x = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
26
|
-
} else if (unsafeCharCodeAt(key
|
|
28
|
+
} else if (unsafeCharCodeAt(key!, 0) == 121) {
|
|
27
29
|
to.y = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
28
|
-
} else if (unsafeCharCodeAt(key
|
|
30
|
+
} else if (unsafeCharCodeAt(key!, 0) == 122) {
|
|
29
31
|
to.z = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -41,14 +43,20 @@ class Vec3 {
|
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
if (key != null) {
|
|
44
|
-
if (unsafeCharCodeAt(key
|
|
46
|
+
if (unsafeCharCodeAt(key!, 0) == 120) {
|
|
45
47
|
to.x = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
46
|
-
} else if (unsafeCharCodeAt(key
|
|
48
|
+
} else if (unsafeCharCodeAt(key!, 0) == 121) {
|
|
47
49
|
to.y = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
48
|
-
} else if (unsafeCharCodeAt(key
|
|
50
|
+
} else if (unsafeCharCodeAt(key!, 0) == 122) {
|
|
49
51
|
to.z = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
50
52
|
}
|
|
51
53
|
}
|
|
54
|
+
|
|
55
|
+
last = 1;
|
|
56
|
+
char = 0;
|
|
57
|
+
inStr = false;
|
|
58
|
+
key = null;
|
|
59
|
+
pos = 0;
|
|
52
60
|
return to;
|
|
53
61
|
}
|
|
54
62
|
}
|
|
@@ -57,35 +65,8 @@ const vec: Vec3 = {
|
|
|
57
65
|
x: 3,
|
|
58
66
|
y: 1,
|
|
59
67
|
z: 8,
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
@inline function istr8<
|
|
63
|
-
T extends number
|
|
64
|
-
>(int: T): string {
|
|
65
|
-
if (int >= 100) {
|
|
66
|
-
const str = changetype<string>(__new(6, idof<String>()));
|
|
67
|
-
store<u16>(changetype<usize>(str), ((int / 100) % 10) + 48);
|
|
68
|
-
store<u16>(changetype<usize>(str), ((int / 10) % 10) + 48, 2);
|
|
69
|
-
store<u16>(changetype<usize>(str), (int % 10) + 48, 4);
|
|
70
|
-
return str;
|
|
71
|
-
} else if (int >= 10) {
|
|
72
|
-
const str = changetype<string>(__new(4, idof<String>()));
|
|
73
|
-
store<u16>(changetype<usize>(str), ((int / 10) % 10) + 48);
|
|
74
|
-
store<u16>(changetype<usize>(str), (int % 10) + 48, 2);
|
|
75
|
-
return str;
|
|
76
|
-
} else {
|
|
77
|
-
const str = changetype<string>(__new(2, idof<String>()));
|
|
78
|
-
store<u16>(changetype<usize>(str), (int % 10) + 48);
|
|
79
|
-
return str;
|
|
80
|
-
}
|
|
81
68
|
}
|
|
82
|
-
|
|
83
|
-
bench("strint", () => {
|
|
84
|
-
blackbox<string>(istr8<i32>(123));
|
|
85
|
-
});
|
|
86
|
-
bench("tostr", () => {
|
|
87
|
-
blackbox<string>((<i32>123).toString());
|
|
88
|
-
});
|
|
69
|
+
/*
|
|
89
70
|
bench("Stringify Object (Vec3)", () => {
|
|
90
71
|
blackbox<string>(vec.__JSON_Serialize());
|
|
91
72
|
});
|
|
@@ -99,10 +80,18 @@ bench("Stringify Number Array", () => {
|
|
|
99
80
|
blackbox(JSON.stringify<i32[]>([1, 2, 3]));
|
|
100
81
|
});
|
|
101
82
|
|
|
102
|
-
bench("Parse Array", () => {
|
|
83
|
+
bench("Parse Number Array", () => {
|
|
103
84
|
blackbox(JSON.parse<i32[]>(blackbox("[1,2,3]")));
|
|
104
85
|
});
|
|
105
86
|
|
|
87
|
+
bench("Stringify String", () => {
|
|
88
|
+
blackbox(JSON.stringify(blackbox('Hello "World!')));
|
|
89
|
+
});
|
|
90
|
+
*/
|
|
91
|
+
bench("Parse String", () => {
|
|
92
|
+
blackbox(JSON.parse<string>(blackbox('"Hello "World!"')));
|
|
93
|
+
});
|
|
94
|
+
/*
|
|
106
95
|
bench("Stringify Boolean Array", () => {
|
|
107
96
|
blackbox(JSON.stringify<boolean[]>([true, false, true]));
|
|
108
97
|
});
|
|
@@ -111,14 +100,6 @@ bench("Stringify String Array", () => {
|
|
|
111
100
|
blackbox(JSON.stringify<string[]>(["a", "b", "c"]));
|
|
112
101
|
});
|
|
113
102
|
|
|
114
|
-
bench("Stringify String", () => {
|
|
115
|
-
blackbox(JSON.stringify(blackbox('Hello "World!')));
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
bench("Parse String", () => {
|
|
119
|
-
blackbox(JSON.parse<string>(blackbox('"Hello "World!"')));
|
|
120
|
-
});
|
|
121
|
-
|
|
122
103
|
bench("Stringify Boolean", () => {
|
|
123
104
|
blackbox(JSON.stringify(blackbox(true)));
|
|
124
105
|
});
|
|
@@ -142,3 +123,4 @@ bench("Stringify Float", () => {
|
|
|
142
123
|
bench("Parse Float", () => {
|
|
143
124
|
blackbox(JSON.parse<f32>(blackbox("3.14")));
|
|
144
125
|
});
|
|
126
|
+
*/
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
-
import {
|
|
3
|
-
u128,
|
|
4
|
-
u128Safe,
|
|
5
|
-
u256,
|
|
6
|
-
u256Safe,
|
|
7
|
-
i128,
|
|
8
|
-
i128Safe,
|
|
9
|
-
i256Safe,
|
|
10
|
-
} from "as-bignum/assembly";
|
|
11
2
|
function canSerde<T>(data: T): void {
|
|
12
3
|
const serialized = JSON.stringify<T>(data);
|
|
13
4
|
const deserialized = JSON.stringify<T>(JSON.parse<T>(serialized));
|
package/bench.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Bench } from "tinybench";
|
|
2
|
+
// Trying a new benchmarking lib.
|
|
3
|
+
// It seems to not warmup long at all, so its probably bad.
|
|
4
|
+
// benchmark will probably be best here
|
|
5
|
+
|
|
6
|
+
// JavaScript Results
|
|
7
|
+
// ┌─────────┬───────────────────────────┬─────────────┬────────────────────┬──────────┬─────────┐
|
|
8
|
+
// │ (index) │ Task Name │ ops / sec │ Average Time(ns) │ Margin │ Samples │
|
|
9
|
+
// ├─────────┼───────────────────────────┼─────────────┼────────────────────┼──────────┼─────────┤
|
|
10
|
+
// │ 0 │ 'Stringify Object (Vec3)' │ '817,816' │ 1222.76 │ '±3.55%' │ 81782 │
|
|
11
|
+
// │ 1 │ 'Parse Object (Vec3)' │ '726,115' │ 1377.19 │ '±3.21%' │ 72612 │
|
|
12
|
+
// │ 2 │ 'Stringify Number Array' │ '1,104,036' │ 905.77 │ '±6.48%' │ 110404 │
|
|
13
|
+
// │ 3 │ 'Parse Number Array' │ '1,114,053' │ 897.62 │ '±2.58%' │ 111406 │
|
|
14
|
+
// │ 4 │ 'Stringify String' │ '1,565,716' │ 638.69 │ '±2.04%' │ 156572 │
|
|
15
|
+
// │ 5 │ 'Parse String' │ '69,568' │ 14374.22 │ '±2.55%' │ 6957 │
|
|
16
|
+
// └─────────┴───────────────────────────┴─────────────┴────────────────────┴──────────┴─────────┘
|
|
17
|
+
|
|
18
|
+
// AssemblyScript Results (Runtime Minimal)
|
|
19
|
+
// ┌─────────┬───────────────────────────┬─────────────┬────────────────────┬──────────┬─────────┐
|
|
20
|
+
// │ (index) │ Task Name │ ops / sec │ Average Time(ns) │ Diff │ Samples │
|
|
21
|
+
// ├─────────┼───────────────────────────┼─────────────┼────────────────────┼──────────┼─────────┤
|
|
22
|
+
// │ 0 │ 'Stringify Object (Vec3)' │ '2,091,000' │ 417.22 │ -805ns │ ------- │
|
|
23
|
+
// │ 1 │ 'Parse Object (Vec3)' │ '1,780,000' │ 539.02 │ -838ns │ ------- |
|
|
24
|
+
// │ 2 │ 'Stringify Number Array' │ '1,920,000' │ 445.43 │ -460ns │ ------- │
|
|
25
|
+
// │ 3 │ 'Parse Number Array' │ '1,660,000' │ 597.17 │ -300ns │ ------- │
|
|
26
|
+
// │ 4 │ 'Stringify String' │ '1,280,000' │ 736.27 │ +97ns │ ------- │
|
|
27
|
+
// │ 5 │ 'Parse String' │ '4,230,000' │ 239.21 │ -14135ns │ ------- │
|
|
28
|
+
// └─────────┴───────────────────────────┴─────────────┴────────────────────┴──────────┴─────────┘
|
|
29
|
+
|
|
30
|
+
const vec = {
|
|
31
|
+
x: 3,
|
|
32
|
+
y: 1,
|
|
33
|
+
z: 8,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let data;
|
|
37
|
+
|
|
38
|
+
const bench = new Bench({ time: 100 })
|
|
39
|
+
|
|
40
|
+
.add("Stringify Object (Vec3)", () => {
|
|
41
|
+
data = JSON.stringify(vec);
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
.add("Parse Object (Vec3)", () => {
|
|
45
|
+
data = JSON.parse('{"x":0,"y":0,"z":0}');
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
.add("Stringify Number Array", () => {
|
|
49
|
+
data = JSON.stringify([1, 2, 3]);
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
.add("Parse Number Array", () => {
|
|
53
|
+
data = JSON.parse("[1,2,3]");
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
.add("Stringify String", () => {
|
|
57
|
+
data = JSON.stringify('Hello "World!');
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
.add("Parse String", () => {
|
|
61
|
+
data = JSON.parse('"Hello "World!"');
|
|
62
|
+
})
|
|
63
|
+
.todo("unimplemented .add");
|
|
64
|
+
|
|
65
|
+
await bench.run();
|
|
66
|
+
|
|
67
|
+
console.table(bench.table());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.51",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"scripts": {
|
|
16
16
|
"aspect": "asp",
|
|
17
|
-
"bench:astral": "astral -Ospeed --noAssert --uncheckedBehavior always",
|
|
17
|
+
"bench:astral": "astral -Ospeed --noAssert --uncheckedBehavior always --runtime minimal",
|
|
18
18
|
"build:test": "asc assembly/test.ts --target test --runtime stub",
|
|
19
19
|
"build:transform": "tsc -p ./transform",
|
|
20
20
|
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"assemblyscript": "^0.27.1",
|
|
30
30
|
"assemblyscript-prettier": "^1.0.7",
|
|
31
31
|
"prettier": "^2.8.4",
|
|
32
|
+
"tinybench": "^2.5.0",
|
|
32
33
|
"typescript": "^4.9.5",
|
|
33
34
|
"visitor-as": "^0.11.4"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"as-bignum": "^0.2.23",
|
|
37
37
|
"as-string-sink": "^0.5.3",
|
|
38
38
|
"as-variant": "^0.4.1"
|
|
39
39
|
},
|