json-as 0.5.41 → 0.5.50
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 +28 -19
- package/asconfig.json +1 -4
- package/assembly/__benches__/as-json.ts +30 -48
- package/assembly/__tests__/as-json.spec.ts +14 -74
- package/assembly/src/json.ts +15 -18
- package/assembly/src/util.ts +21 -6
- package/assembly/test.ts +18 -9
- package/bench.js +67 -0
- package/package.json +3 -3
- package/transform/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,25 +93,34 @@ Fully supports:
|
|
|
93
93
|
|
|
94
94
|
## Performance
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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.
|
|
98
|
+
|
|
99
|
+
Tests are run on Ubuntu/WSL2 with a AMD Ryzen 9 CPU
|
|
100
|
+
|
|
101
|
+
JavaScript Results (TinyBench/NodeJS 19)
|
|
102
|
+
┌───────────────────────────┬─────────────┬────────────────────┬──────────┐
|
|
103
|
+
│ Task Name │ ops / sec │ Average Time(ns) │ Margin │
|
|
104
|
+
├───────────────────────────┼─────────────┼────────────────────┼──────────┤
|
|
105
|
+
│ 'Stringify Object (Vec3)' │ '817,816' │ 1222.76 │ '±3.55%' │
|
|
106
|
+
│ 'Parse Object (Vec3)' │ '726,115' │ 1377.19 │ '±3.21%' │
|
|
107
|
+
│ 'Stringify Number Array' │ '1,104,036' │ 905.77 │ '±6.48%' │
|
|
108
|
+
│ 'Parse Number Array' │ '1,114,053' │ 897.62 │ '±2.58%' │
|
|
109
|
+
│ 'Stringify String' │ '1,565,716' │ 638.69 │ '±2.04%' │
|
|
110
|
+
│ 'Parse String' │ '69,568' │ 14374.22 │ '±2.55%' │
|
|
111
|
+
└───────────────────────────┴─────────────┴────────────────────┴──────────┘
|
|
112
|
+
|
|
113
|
+
AssemblyScript Results (Runtime Minimal)
|
|
114
|
+
┌───────────────────────────┬─────────────┬────────────────────┬──────────┐
|
|
115
|
+
│ Task Name │ ops / sec │ Average Time(ns) │ Diff │
|
|
116
|
+
├───────────────────────────┼─────────────┼────────────────────┼──────────┤
|
|
117
|
+
│ 'Stringify Object (Vec3)' │ '2,091,000' │ 417.22 │ -805ns │
|
|
118
|
+
│ 'Parse Object (Vec3)' │ '1,780,000' │ 539.02 │ -838ns |
|
|
119
|
+
│ 'Stringify Number Array' │ '1,920,000' │ 445.43 │ -460ns │
|
|
120
|
+
│ 'Parse Number Array' │ '1,660,000' │ 597.17 │ -300ns │
|
|
121
|
+
│ 'Stringify String' │ '1,280,000' │ 736.27 │ +97ns │
|
|
122
|
+
│ 'Parse String' │ '4,230,000' │ 239.21 │ -14135ns │
|
|
123
|
+
└───────────────────────────┴─────────────┴────────────────────┴──────────┘
|
|
115
124
|
|
|
116
125
|
## Issues
|
|
117
126
|
|
package/asconfig.json
CHANGED
|
@@ -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));
|
|
@@ -33,13 +24,24 @@ class Player {
|
|
|
33
24
|
isVerified: boolean;
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
class Nullable {}
|
|
27
|
+
class Nullable { }
|
|
37
28
|
type Null = Nullable | null;
|
|
38
29
|
|
|
39
30
|
describe("Ser/de Nulls", () => {
|
|
40
31
|
canSerde<Null>(null);
|
|
41
32
|
});
|
|
42
33
|
|
|
34
|
+
describe("Ser/de Strings", () => {
|
|
35
|
+
it("should ser/de strings", () => {
|
|
36
|
+
canSerde<string>("abcdefg");
|
|
37
|
+
canSerde<string>('st"ring" w""ith quotes"');
|
|
38
|
+
canSerde<string>('string \"with random spa\nces and \nnewlines\n\n\n');
|
|
39
|
+
canSerde<string>(
|
|
40
|
+
'string with colon : comma , brace [ ] bracket { } and quote " and other quote \\"'
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
43
45
|
describe("Ser/de Numbers", () => {
|
|
44
46
|
it("should ser/de integers", () => {
|
|
45
47
|
canSerde<i32>(0);
|
|
@@ -48,34 +50,6 @@ describe("Ser/de Numbers", () => {
|
|
|
48
50
|
canSerde<u64>(101);
|
|
49
51
|
canSerde<i32>(-100);
|
|
50
52
|
canSerde<i64>(-101);
|
|
51
|
-
|
|
52
|
-
// canSerde<u128>(u128.from("0"))
|
|
53
|
-
// canSerde<u128>(u128.from("100"))
|
|
54
|
-
// canSerde<u128>(u128.from("101"))
|
|
55
|
-
|
|
56
|
-
/* canSerde<u128Safe>(u128Safe.from("0"))
|
|
57
|
-
canSerde<u128Safe>(u128Safe.from("100"))
|
|
58
|
-
canSerde<u128Safe>(u128Safe.from("101"))
|
|
59
|
-
|
|
60
|
-
canSerde<u256>(u256.fromU128(u128.from("0")))
|
|
61
|
-
canSerde<u256>(u256.fromU128(u128.from("100")))
|
|
62
|
-
canSerde<u256>(u256.fromU128(u128.from("101")))
|
|
63
|
-
|
|
64
|
-
canSerde<u256Safe>(u256Safe.fromU128(u128.from("0")))
|
|
65
|
-
canSerde<u256Safe>(u256Safe.fromU128(u128.from("100")))
|
|
66
|
-
canSerde<u256Safe>(u256Safe.fromU128(u128.from("101")))
|
|
67
|
-
|
|
68
|
-
canSerde<i128>(i128.from("0"))
|
|
69
|
-
canSerde<i128>(i128.from("100"))
|
|
70
|
-
canSerde<i128>(i128.from("101"))
|
|
71
|
-
|
|
72
|
-
canSerde<i128Safe>(i128Safe.from("0"))
|
|
73
|
-
canSerde<i128Safe>(i128Safe.from("100"))
|
|
74
|
-
canSerde<i128Safe>(i128Safe.from("101"))
|
|
75
|
-
canSerde<i128Safe>(i128Safe.from("-100"))
|
|
76
|
-
canSerde<i128Safe>(i128Safe.from("-101"))
|
|
77
|
-
*/
|
|
78
|
-
//canSerde<i256Safe>(new i256Safe(10, 11, 500, 501))
|
|
79
53
|
});
|
|
80
54
|
|
|
81
55
|
it("should ser/de floats", () => {
|
|
@@ -98,30 +72,13 @@ describe("Ser/de Numbers", () => {
|
|
|
98
72
|
canSerde<boolean>(false);
|
|
99
73
|
});
|
|
100
74
|
|
|
101
|
-
it("should ser/de strings", () => {
|
|
102
|
-
canSerde<string>("abcdefg");
|
|
103
|
-
canSerde<string>('st"ring" w""ith quotes"');
|
|
104
|
-
canSerde<string>(
|
|
105
|
-
'string \t\r\\"with ran\tdom spa\nces and \nnewlines\n\n\n'
|
|
106
|
-
);
|
|
107
|
-
canSerde<string>(
|
|
108
|
-
'string with colon : comma , brace [ ] bracket { } and quote " and other quote \\"'
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
75
|
it("should ser/de BigInt objects", () => {
|
|
113
|
-
|
|
76
|
+
canSerde<i32>(0);
|
|
114
77
|
|
|
115
78
|
canSerde<u32>(100);
|
|
116
79
|
canSerde<u64>(101);
|
|
117
80
|
canSerde<i32>(-100);
|
|
118
81
|
canSerde<i64>(-101);
|
|
119
|
-
canSerde<u128>(u128.from("0"))
|
|
120
|
-
canSerde<u128>(u128.from("100"))
|
|
121
|
-
canSerde<u128>(u128.from("101"))
|
|
122
|
-
canSerde<u128>(u128.from("-100"))
|
|
123
|
-
canSerde<u128>(u128.from("-101"))
|
|
124
|
-
*/
|
|
125
82
|
});
|
|
126
83
|
});
|
|
127
84
|
|
|
@@ -144,13 +101,7 @@ describe("Ser/de Array", () => {
|
|
|
144
101
|
});
|
|
145
102
|
|
|
146
103
|
it("should ser/de string arrays", () => {
|
|
147
|
-
|
|
148
|
-
canSerde<string[]>([
|
|
149
|
-
"abcdefg",
|
|
150
|
-
'st"ring" w""ith quotes"',
|
|
151
|
-
'string \t\r"with ran\tdom spa\nces and \nnewlines\n\n\n',
|
|
152
|
-
'string with colon : comma , brace [ ] bracket { } and quote " and other quote "',
|
|
153
|
-
]);
|
|
104
|
+
canSerde<string[]>(['string \"with random spa\nces and \nnewlines\n\n\n']);
|
|
154
105
|
});
|
|
155
106
|
|
|
156
107
|
it("should ser/de nested integer arrays", () => {
|
|
@@ -174,17 +125,6 @@ describe("Ser/de Array", () => {
|
|
|
174
125
|
canSerde<boolean[][]>([[true], [false]]);
|
|
175
126
|
});
|
|
176
127
|
|
|
177
|
-
it("should ser/de string arrays", () => {
|
|
178
|
-
canSerde<string[][]>([
|
|
179
|
-
["abcdefg"],
|
|
180
|
-
['st"ring" w""ith quotes"'],
|
|
181
|
-
['string \t\r\\"with ran\tdom spa\nces and \nnewlines\n\n\n'],
|
|
182
|
-
[
|
|
183
|
-
'string with colon : comma , brace [ ] bracket { } and quote " and other quote \\"',
|
|
184
|
-
],
|
|
185
|
-
]);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
128
|
it("should ser/de object arrays", () => {
|
|
189
129
|
canSerde<Vec3[]>([
|
|
190
130
|
{
|
package/assembly/src/json.ts
CHANGED
|
@@ -272,10 +272,10 @@ export namespace JSON {
|
|
|
272
272
|
if (char === 34 || char === 92) {
|
|
273
273
|
result += (<string>data).slice(last, i) + "\\";
|
|
274
274
|
last = i;
|
|
275
|
-
i++;
|
|
275
|
+
//i++;
|
|
276
276
|
} else if (char <= 13 && char >= 8) {
|
|
277
277
|
result += (<string>data).slice(last, i);
|
|
278
|
-
last =
|
|
278
|
+
last = i + 1;
|
|
279
279
|
switch (char) {
|
|
280
280
|
case 8: {
|
|
281
281
|
result += "\\b";
|
|
@@ -322,40 +322,37 @@ export namespace JSON {
|
|
|
322
322
|
result += data.slice(last, i - 1);
|
|
323
323
|
if (char === 34) {
|
|
324
324
|
result += '"';
|
|
325
|
-
last =
|
|
326
|
-
} else if (char === 110) {
|
|
327
|
-
result += "\n";
|
|
328
|
-
last = ++i;
|
|
329
|
-
// 92 98 114 116 102 117
|
|
325
|
+
last = i + 1;
|
|
330
326
|
} else if (char >= 92 && char <= 117) {
|
|
331
327
|
switch (char) {
|
|
332
328
|
case 92: {
|
|
333
329
|
result += "\\";
|
|
334
|
-
last =
|
|
330
|
+
last = i + 1;
|
|
335
331
|
break;
|
|
336
332
|
}
|
|
337
333
|
case 98: {
|
|
338
334
|
result += "\b";
|
|
339
|
-
last =
|
|
335
|
+
last = i + 1;
|
|
340
336
|
break;
|
|
341
337
|
}
|
|
342
|
-
case 110: {
|
|
343
|
-
result += "\n";
|
|
344
|
-
last = ++i;
|
|
345
|
-
}
|
|
346
338
|
case 102: {
|
|
347
339
|
result += "\f";
|
|
348
|
-
last =
|
|
340
|
+
last = i + 1;
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
case 110: {
|
|
344
|
+
result += "\n";
|
|
345
|
+
last = i + 1;
|
|
349
346
|
break;
|
|
350
347
|
}
|
|
351
348
|
case 114: {
|
|
352
349
|
result += "\r";
|
|
353
|
-
last =
|
|
350
|
+
last = i + 1;
|
|
354
351
|
break;
|
|
355
352
|
}
|
|
356
353
|
case 116: {
|
|
357
354
|
result += "\t";
|
|
358
|
-
last =
|
|
355
|
+
last = i + 1;
|
|
359
356
|
break;
|
|
360
357
|
}
|
|
361
358
|
default: {
|
|
@@ -366,7 +363,7 @@ export namespace JSON {
|
|
|
366
363
|
) {
|
|
367
364
|
result += "\u000b";
|
|
368
365
|
i += 4;
|
|
369
|
-
last =
|
|
366
|
+
last = i + 1;
|
|
370
367
|
}
|
|
371
368
|
break;
|
|
372
369
|
}
|
|
@@ -579,7 +576,7 @@ export namespace JSON {
|
|
|
579
576
|
lastPos = i;
|
|
580
577
|
} else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
|
|
581
578
|
instr = false;
|
|
582
|
-
result.push(data.slice(lastPos
|
|
579
|
+
result.push(parseString(data.slice(lastPos, i)));
|
|
583
580
|
}
|
|
584
581
|
}
|
|
585
582
|
}
|
package/assembly/src/util.ts
CHANGED
|
@@ -89,13 +89,28 @@ export function getArrayDepth<T>(depth: i32 = 1): i32 {
|
|
|
89
89
|
export function atoi_fast<T extends number>(str: string, offset: i32 = 0): T {
|
|
90
90
|
// @ts-ignore
|
|
91
91
|
let val: T = 0;
|
|
92
|
-
|
|
92
|
+
let firstChar = load<u16>(changetype<usize>(str) + <usize>offset);
|
|
93
|
+
if (firstChar === 45) {
|
|
94
|
+
offset += 2;
|
|
95
|
+
for (; offset < str.length << 1; offset += 2) {
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
val =
|
|
98
|
+
(val << 1) +
|
|
99
|
+
(val << 3) +
|
|
100
|
+
(load<u16>(changetype<usize>(str) + <usize>offset) - 48);
|
|
101
|
+
// We use load because in this case, there is no need to have bounds-checking
|
|
102
|
+
}
|
|
93
103
|
// @ts-ignore
|
|
94
|
-
val =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
val = -val;
|
|
105
|
+
} else {
|
|
106
|
+
for (; offset < str.length << 1; offset += 2) {
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
val =
|
|
109
|
+
(val << 1) +
|
|
110
|
+
(val << 3) +
|
|
111
|
+
(load<u16>(changetype<usize>(str) + <usize>offset) - 48);
|
|
112
|
+
// We use load because in this case, there is no need to have bounds-checking
|
|
113
|
+
}
|
|
99
114
|
}
|
|
100
115
|
return val;
|
|
101
116
|
}
|
package/assembly/test.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { JSON } from "./src/json";
|
|
2
2
|
import { atoi_fast, parseSciInteger } from "./src/util";
|
|
3
3
|
import * as a from "util/number";
|
|
4
|
+
// "st\"ring\" w\"\"ith quotes\""
|
|
5
|
+
|
|
4
6
|
@json
|
|
5
7
|
class Vec3 {
|
|
6
8
|
x!: f32;
|
|
@@ -53,18 +55,25 @@ console.log("123 - " + parseSciInteger<i32>("123").toString());
|
|
|
53
55
|
console.log("1230 - " + parseSciInteger<i32>("123e1").toString());
|
|
54
56
|
console.log("12300 - " + parseSciInteger<i32>("123e2").toString());
|
|
55
57
|
console.log("123000 - " + parseSciInteger<i32>("123e3").toString());
|
|
56
|
-
console.log("
|
|
58
|
+
console.log("12 - " + parseSciInteger<i32>("123e-1").toString());
|
|
57
59
|
console.log(parseSciInteger<i32>("100").toString());
|
|
58
60
|
console.log(parseSciInteger<i32>("-100").toString());
|
|
59
61
|
|
|
60
|
-
console.log(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
)
|
|
62
|
+
console.log(JSON.stringify("abcdefg"));
|
|
63
|
+
console.log('"abcdefg"')
|
|
64
|
+
console.log(JSON.stringify('st"ring" w""ith quotes"'));
|
|
65
|
+
console.log('"st\\"ring\\" w\\"\\"ith quotes\\""')
|
|
66
|
+
console.log(JSON.stringify(['string "with random spa\nces and \nnewlines\n\n\n']));
|
|
67
|
+
console.log(JSON.stringify(JSON.parse<string[]>(JSON.stringify(['string "with random spa\nces and \nnewlines\n\n\n']))));
|
|
68
|
+
console.log('"string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"')
|
|
69
|
+
console.log(JSON.stringify('string with colon : comma , brace [ ] bracket { } and quote " and other quote "'));
|
|
70
|
+
/*console.log(JSON.stringify(JSON.parse<string[]>(JSON.stringify([
|
|
71
|
+
"abcdefg",
|
|
72
|
+
'st"ring" w""ith quotes"',
|
|
73
|
+
'string \t\r"with ran\tdom spa\nces and \nnewlines\n\n\n',
|
|
74
|
+
'string with colon : comma , brace [ ] bracket { } and quote " and other quote "',
|
|
75
|
+
]))));
|
|
76
|
+
console.log('["abcdefg","st\"ring\" w\"\"ith quotes\"","string \t\r\"with ran\tdom spa\nces and \nnewlines\n\n\n","string with colon : comma , brace [ ] bracket { } and quote \" and other quote \""]');/*
|
|
68
77
|
console.log(
|
|
69
78
|
JSON.stringify(
|
|
70
79
|
JSON.parse<string[]>(
|
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.50",
|
|
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
|
},
|