json-as 0.5.52 → 0.5.56

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.
@@ -1,27 +1,23 @@
1
1
  import { StringSink } from "as-string-sink/assembly";
2
- import { CharCode, isSpace } from "util/string";
2
+ import { isSpace } from "util/string";
3
3
  import { backSlashCode, quoteCode } from "./chars";
4
4
 
5
- // @ts-ignore
6
- @inline
7
- export function unsafeCharCodeAt(data: string, pos: i32): i32 {
5
+ // @ts-ignore: Decorator
6
+ @inline export function unsafeCharCodeAt(data: string, pos: i32): i32 {
8
7
  return load<u16>(changetype<usize>(data) + ((<usize>pos) << 1));
9
8
  }
10
9
 
11
- // @ts-ignore
12
- @inline
13
- export function removeWhitespace(data: string): string {
10
+ // @ts-ignore: Decorator
11
+ @inline export function removeWhitespace(data: string): string {
14
12
  const result = new StringSink();
15
13
  let instr = false;
16
14
  for (let i = 0; i < data.length; i++) {
17
15
  const char = data.charCodeAt(i);
18
16
  if (instr === false && char === quoteCode) instr = true;
19
17
  else if (
20
- instr === true &&
21
- char === quoteCode &&
22
- data.charCodeAt(i - 1) !== backSlashCode
23
- )
24
- instr = false;
18
+ instr === true && char === quoteCode
19
+ && data.charCodeAt(i - 1) !== backSlashCode
20
+ ) instr = false;
25
21
 
26
22
  if (instr === false) {
27
23
  if (!isSpace(char)) result.write(data.charAt(i));
@@ -32,9 +28,8 @@ export function removeWhitespace(data: string): string {
32
28
  return result.toString();
33
29
  }
34
30
 
35
- // @ts-ignore
36
- @inline
37
- export function escapeChar(char: string): string {
31
+ // @ts-ignore: Decorator
32
+ @inline export function escapeChar(char: string): string {
38
33
  switch (unsafeCharCodeAt(char, 0)) {
39
34
  case 0x22:
40
35
  return '\\"';
@@ -63,143 +58,169 @@ export function escapeChar(char: string): string {
63
58
  * @returns depth of array
64
59
  */
65
60
 
66
- // @ts-ignore
67
- @inline
68
- export function getArrayDepth<T>(depth: i32 = 1): i32 {
69
- // @ts-ignore
61
+ // @ts-ignore: Decorator
62
+ @inline export function getArrayDepth<T extends ArrayLike>(depth: i32 = 1): i32 {
70
63
  if (!isArray<T>()) {
71
64
  return 0;
72
- // @ts-ignore
73
65
  } else if (isArray<valueof<T>>()) {
74
66
  depth++;
75
- // @ts-ignore
76
67
  return getArrayDepth<valueof<T>>(depth);
77
68
  } else {
78
69
  return depth;
79
70
  }
80
71
  }
81
72
 
82
- // Scientific Notation Integer Parsing - SNIP
83
- // This is absolutely the fastest algorithm I could think of while adding full support for Scientific Notation
84
- // Loads 32 bits and retrieves the high/low bits
85
- // Here are some benchmarks
86
- // Parsing: "12345"
87
- // Results are spread over 5000ms
88
- // SNIP: 207M iterations
89
- // ATOI: 222M iterations
90
- // STD (parseInt): 162M iterations
91
- export function snip_fast<T extends number>(str: string, offset: u32 = 0): T {
92
- let ch: u32 = load<u32>(changetype<usize>(str));
93
- const h = ch & 0xFFFF;
94
- if (h === 48) return 0 as T;
95
- const isNegative = h === 45; // Check if the number is negative
96
- let val: T = 0 as T;
97
- const len = u32(str.length << 1);
98
- if (isNegative) {
99
- if ((ch >> 16) === 48) return -0 as T;
100
- offset += 2;
101
- if (len >= 4) {
102
- // 32-bit route
103
- for (; offset < (len - 3); offset += 4) {
104
- ch = load<u32>(changetype<usize>(str) + <usize>offset);
105
- const low = ch & 0xFFFF;
106
- const high = ch >> 16;
107
- // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire.
108
- if (low > 57) {
109
- // The first char (f) is E or e
110
- // We push the offset up by two and apply the notation.
111
- offset += 2;
112
- let exp: i32 = atoi_fast<i32>(str, offset);
113
- if (exp < 0) {
114
- for (let i = 0; i < exp; i++) {
115
- val = (val / 10) as T;
73
+ /** Scientific Notation Integer Parsing - SNIP
74
+ * This is absolutely the fastest algorithm I could think of while adding full support for Scientific Notation
75
+ * Loads 32 bits and retrieves the high/low bits.
76
+ * The reason why we only load 4 bytes at a time is that numbers in the 32-bit range are 7 chars long at most.
77
+ * Using SIMD or 64 bit loads would only work well when parsing large 128+ numbers.
78
+ *
79
+ * Here are some benchmarks
80
+ * Parsing: "12345"
81
+ * Results are spread over 5000ms
82
+ *
83
+ * SNIP: 270M iterations
84
+ * ATOI: 285M iterations
85
+ * ParseInt: 176M iterations
86
+ *
87
+ * @param str - Any number. Can include scientific notation.
88
+ */
89
+ // @ts-ignore: Decorator
90
+ @inline export function snip_fast<T extends number>(str: string, len: u32 = 0, offset: u32 = 0): T {
91
+ if (isSigned<T>()) {
92
+ const firstChar: u32 = load<u16>(changetype<usize>(str));
93
+ if (firstChar === 48) return 0 as T;
94
+ const isNegative = firstChar === 45; // Check if the number is negative
95
+ let val: T = 0 as T;
96
+ if (len == 0) len = u32(str.length << 1);
97
+ if (isNegative) {
98
+ offset += 2;
99
+ if (len >= 4) {
100
+ // 32-bit route
101
+ for (; offset < (len - 3); offset += 4) {
102
+ const ch = load<u32>(changetype<usize>(str) + <usize>offset);
103
+ const low = ch & 0xFFFF;
104
+ const high = ch >> 16;
105
+ // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire.
106
+ if (low > 57) {
107
+ // The first char (f) is E or e
108
+ // We push the offset up by two and apply the notation.
109
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
110
+ return -(val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
111
+ } else {
112
+ // Inlined this operation instead of using a loop
113
+ return -(val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
116
114
  }
117
- } else {
118
- for (let i = 0; i < exp; i++) {
119
- val = (val * 10) as T;
115
+ } else if (high > 57) {
116
+ // The first char (f) is E or e
117
+ // We push the offset up by two and apply the notation.
118
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
119
+ return -(val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
120
+ } else {
121
+ // Inlined this operation instead of using a loop
122
+ return -(val * (10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1))) as T;
120
123
  }
124
+ } else {
125
+ val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T;
121
126
  }
122
- return -val as T;
123
- } else if (high > 57) {
127
+ }
128
+ }
129
+ // Finish up the remainder with 16 bits.
130
+ for (; offset < len; offset += 2) {
131
+ const ch = load<u16>(changetype<usize>(str) + <usize>offset);
132
+ // 9 is 57. E and e are larger. Assumes valid JSON.
133
+ if (ch > 57) {
124
134
  // The first char (f) is E or e
125
135
  // We push the offset up by two and apply the notation.
126
- offset += 4;
127
- let exp: i32 = atoi_fast<i32>(str, offset);
128
- if (exp < 0) {
129
- for (let i = 0; i < exp; i++) {
130
- val = (val / 10) as T;
131
- }
136
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
137
+ return -(val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
132
138
  } else {
133
- for (let i = 0; i < exp; i++) {
134
- val = (val * 10) as T;
135
- }
139
+ // Inlined this operation instead of using a loop
140
+ return -(val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
136
141
  }
137
- return -val as T;
138
142
  } else {
139
- val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T;
143
+ val = (val * 10) + (ch - 48) as T;
140
144
  }
141
145
  }
142
- }
143
- // Finish up the remainder with 16 bits.
144
- for (; offset < len; offset += 2) {
145
- ch = load<u16>(changetype<usize>(str) + <usize>offset);
146
- // 9 is 57. E and e are larger. Assumes valid JSON.
147
- if (ch > 57) {
148
- // The first char (f) is E or e
149
- // We push the offset up by two and apply the notation.
150
- offset += 2;
151
- let exp: i32 = atoi_fast<i32>(str, offset);
152
- if (exp < 0) {
153
- for (let i = 0; i > exp; i--) {
154
- val = (val / 10) as T;
146
+ return -val as T;
147
+ } else {
148
+ if (len >= 4) {
149
+ // Duplet 16 bit lane load
150
+ for (; offset < (len - 3); offset += 4) {
151
+ const ch = load<u32>(changetype<usize>(str) + <usize>offset);
152
+ const low = ch & 0xFFFF;
153
+ const high = ch >> 16;
154
+ // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire.
155
+ if (low > 57) {
156
+ // The first char (f) is E or e
157
+ // We push the offset up by two and apply the notation.
158
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
159
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
160
+ } else {
161
+ // Inlined this operation instead of using a loop
162
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
163
+ }
164
+ } else if (high > 57) {
165
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
166
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
167
+ } else {
168
+ // Inlined this operation instead of using a loop
169
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1))) as T;
170
+ }
171
+ } else {
172
+ // Optimized with multiplications and shifts.
173
+ val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T;
155
174
  }
156
- } else {
157
- for (let i = 0; i < exp; i++) {
158
- val = (val * 10) as T;
175
+ }
176
+ }
177
+ // Cover the remaining numbers with 16 bit loads.
178
+ for (; offset < len; offset += 2) {
179
+ const ch = load<u16>(changetype<usize>(str) + <usize>offset);
180
+ // 0's char is 48 and 9 is 57. Anything above this range would signify an exponent (e or E).
181
+ // e is 101 and E is 69.
182
+ if (ch > 57) {
183
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
184
+ val = (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
185
+ } else {
186
+ // Inlined this operation instead of using a loop
187
+ val = (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
159
188
  }
189
+ return val as T;
190
+ } else {
191
+ val = (val * 10) + (ch - 48) as T;
160
192
  }
161
- return -val as T;
162
- } else {
163
- val = (val * 10) + (ch - 48) as T;
164
193
  }
194
+ return val as T;
165
195
  }
166
- return -val as T;
167
196
  } else {
197
+ const firstChar: u32 = load<u16>(changetype<usize>(str));
198
+ if (firstChar === 48) return 0 as T;
199
+ let val: T = 0 as T;
200
+ if (len == 0) len = u32(str.length << 1);
168
201
  if (len >= 4) {
169
202
  // Duplet 16 bit lane load
170
203
  for (; offset < (len - 3); offset += 4) {
171
- ch = load<u32>(changetype<usize>(str) + <usize>offset);
204
+ const ch = load<u32>(changetype<usize>(str) + <usize>offset);
172
205
  const low = ch & 0xFFFF;
173
206
  const high = ch >> 16;
174
207
  // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire.
175
208
  if (low > 57) {
176
209
  // The first char (f) is E or e
177
210
  // We push the offset up by two and apply the notation.
178
- offset += 2;
179
- let exp: i32 = atoi_fast<i32>(str, offset);
180
- if (exp < 0) {
181
- for (let i = 0; i < exp; i++) {
182
- val = (val / 10) as T;
183
- }
211
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
212
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
184
213
  } else {
185
- for (let i = 0; i < exp; i++) {
186
- val = (val * 10) as T;
187
- }
214
+ // Inlined this operation instead of using a loop
215
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
188
216
  }
189
- return val as T;
190
217
  } else if (high > 57) {
191
- offset += 4;
192
- let exp: i32 = atoi_fast<i32>(str, offset);
193
- if (exp < 0) {
194
- for (let i = 0; i < exp; i++) {
195
- val = (val / 10) as T;
196
- }
218
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
219
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
197
220
  } else {
198
- for (let i = 0; i < exp; i++) {
199
- val = (val * 10) as T;
200
- }
221
+ // Inlined this operation instead of using a loop
222
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1))) as T;
201
223
  }
202
- return val as T;
203
224
  } else {
204
225
  // Optimized with multiplications and shifts.
205
226
  val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T;
@@ -208,22 +229,16 @@ export function snip_fast<T extends number>(str: string, offset: u32 = 0): T {
208
229
  }
209
230
  // Cover the remaining numbers with 16 bit loads.
210
231
  for (; offset < len; offset += 2) {
211
- ch = load<u16>(changetype<usize>(str) + <usize>offset);
232
+ const ch = load<u16>(changetype<usize>(str) + <usize>offset);
212
233
  // 0's char is 48 and 9 is 57. Anything above this range would signify an exponent (e or E).
213
234
  // e is 101 and E is 69.
214
235
  if (ch > 57) {
215
- offset += 2;
216
- let exp: i32 = atoi_fast<i32>(str, offset);
217
- if (exp < 0) {
218
- for (let i = 0; i > exp; i--) {
219
- val = (val / 10) as T;
220
- }
236
+ if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
237
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
221
238
  } else {
222
- for (let i = 0; i < exp; i++) {
223
- val = (val * 10) as T;
224
- }
239
+ // Inlined this operation instead of using a loop
240
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
225
241
  }
226
- return val as T;
227
242
  } else {
228
243
  val = (val * 10) + (ch - 48) as T;
229
244
  }
@@ -234,34 +249,37 @@ export function snip_fast<T extends number>(str: string, offset: u32 = 0): T {
234
249
 
235
250
  /**
236
251
  * Implementation of ATOI. Can be much much faster with SIMD.
237
- * Benchmark: 40-46m ops/s
238
252
  */
239
253
 
240
254
  // @ts-ignore
241
- @inline
242
- export function atoi_fast<T extends number>(str: string, offset: u32 = 0): T {
255
+ @global @inline export function __atoi_fast<T extends number>(str: string, start: u32 = 0, end: u32 = 0): T {
243
256
  // @ts-ignore
244
257
  let val: T = 0;
245
- const len = u32(str.length << 1);
246
- if (load<u16>(changetype<usize>(str) + <usize>offset) === 45) {
247
- offset += 2;
248
- for (; offset < len; offset += 2) {
249
- // @ts-ignore
250
- val = (val << 1) + (val << 3) + (load<u16>(changetype<usize>(str) + <usize>offset) - 48);
258
+ if (!end) end = start + u32(str.length << 1);
259
+ if (isSigned<T>()) {
260
+ // Negative path
261
+ if (load<u16>(changetype<usize>(str) + <usize>start) === 45) {
262
+ start += 2;
263
+ for (; start < end; start += 2) {
264
+ val = (val * 10) + (load<u16>(changetype<usize>(str) + <usize>start) - 48) as T;
265
+ }
266
+ return -val as T;
267
+ } else {
268
+ for (; start < end; start += 2) {
269
+ val = ((val * 10) + (load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
270
+ }
271
+ return val as T;
251
272
  }
252
- // @ts-ignore
253
- return -val;
254
273
  } else {
255
- for (; offset < len; offset += 2) {
256
- // @ts-ignore
257
- val = (val << 1) + (val << 3) + (load<u16>(changetype<usize>(str) + <usize>offset) - 48);
274
+ for (; start < end; start += 2) {
275
+ val = ((val * 10) + (load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
258
276
  }
259
- return val;
277
+ return val as T;
260
278
  }
261
279
  }
262
280
 
263
281
  /**
264
- * Parses an integer using atoi_fast and applies the appended exponential number to it as scientific notation.
282
+ * Parses an integer using __atoi_fast and applies the appended exponential number to it as scientific notation.
265
283
  * Benchmark: Hovers around 30m ops/s
266
284
  * Only safe if the string is valid.
267
285
  * @param str integer to parse. example: 123e1, 123e-1, 123E100
@@ -269,8 +287,7 @@ export function atoi_fast<T extends number>(str: string, offset: u32 = 0): T {
269
287
  */
270
288
 
271
289
  // @ts-ignore
272
- @inline
273
- export function parseSciInteger<T extends number>(str: string): T {
290
+ @inline export function parseSciInteger<T extends number>(str: string): T {
274
291
  // @ts-ignore
275
292
  let val: T = 0;
276
293
  let offset = 0;
@@ -284,12 +301,12 @@ export function parseSciInteger<T extends number>(str: string): T {
284
301
  const char = load<u16>(changetype<usize>(str) + <usize>(offset += 2));
285
302
  if (char === 45) {
286
303
  // @ts-ignore
287
- val /= sciNote<T>(atoi_fast<T>(str, (offset += 2)));
304
+ val /= sciNote<T>(__atoi_fast<T>(str, (offset += 2)));
288
305
  // @ts-ignore
289
306
  return val;
290
307
  } else {
291
308
  // @ts-ignore
292
- val *= sciNote<T>(atoi_fast<T>(str, offset));
309
+ val *= sciNote<T>(__atoi_fast<T>(str, offset));
293
310
  // @ts-ignore
294
311
  return val;
295
312
  }
@@ -299,25 +316,35 @@ export function parseSciInteger<T extends number>(str: string): T {
299
316
  // We use load because in this case, there is no need to have bounds-checking
300
317
  }
301
318
  if (firstChar === 45) {
302
- val = -val;
319
+ val = -val as T;
303
320
  }
304
321
  return val;
305
322
  }
306
323
 
307
324
  // @ts-ignore
308
- @inline
309
- function sciNote<T extends number>(num: T): T {
325
+ @inline function sciNote<T extends number>(num: T): T {
310
326
  let res = 1;
311
327
  // @ts-ignore
312
328
  if (num > 0) {
313
- for (let i: T = 0; i < num; i++) {
329
+ for (let i: T = <T>0; i < num; i++) {
314
330
  res *= 10;
315
331
  }
316
332
  } else {
317
- for (let i: T = 0; i < num; i++) {
333
+ for (let i: T = <T>0; i < num; i++) {
318
334
  res /= 10;
319
335
  }
320
336
  }
321
337
  // @ts-ignore
322
338
  return res;
339
+ }
340
+
341
+ // @ts-ignore
342
+ @inline function equalsSlice(p1_data: string, p1_start: i32, p1_end: i32, p2_data: string, p2_start: i32, p2_end: i32): boolean {
343
+ const p1_len = p1_end - p1_start;
344
+ const p2_len = p2_end - p2_start;
345
+ if (p1_len != p2_len) return false;
346
+ if (p1_len == 2) {
347
+ return load<u16>(changetype<usize>(p1_data) + p1_start) == load<u16>(changetype<usize>(p2_data) + p2_start)
348
+ }
349
+ return memory.compare(changetype<usize>(p1_data) + p1_start, changetype<usize>(p2_data) + p2_start, p1_len) === 0;
323
350
  }
package/assembly/test.ts CHANGED
@@ -1,89 +1,68 @@
1
- import { snip_fast } from "./src/util";
2
-
3
- import { JSON } from "./src/json";
1
+ import { bench, blackbox } from "../../../WebAssembly/benchmark-wasm/assembly/bench";
2
+ import { JSON, serializeString } from "./src/json";
3
+ // @ts-ignore
4
4
  @json
5
5
  class Vec3 {
6
- x!: f64;
7
- y!: f64;
8
- z!: f64;
6
+ x: f64;
7
+ y: f64;
8
+ z: f64;
9
9
  }
10
10
 
11
+ // @ts-ignore
11
12
  @json
12
13
  class Player {
13
- firstName!: string;
14
- lastName!: string;
15
- lastActive!: i32[];
16
- age!: i32;
17
- pos!: Vec3 | null;
18
- isVerified!: boolean;
14
+ firstName: string;
15
+ lastName: string;
16
+ lastActive: i32[];
17
+ age: i32;
18
+ pos: Vec3 | null;
19
+ isVerified: boolean;
19
20
  }
20
21
 
21
- const player: Player = {
22
- firstName: "Emmet",
23
- lastName: "West",
24
- lastActive: [8, 27, 2022],
25
- age: 23,
26
- pos: {
22
+ const vec: Vec3 = {
27
23
  x: 3.4,
28
24
  y: 1.2,
29
25
  z: 8.3,
30
- },
31
- isVerified: true,
32
- };
33
-
34
- const vec: Vec3 = {
35
- x: 3,
36
- y: 1,
37
- z: 8,
38
- };
26
+ }
39
27
 
40
- function canSerde<T>(data: T, toBe: string = ""): void {
41
- if (!toBe) toBe = JSON.stringify<T>(data);
42
- const deserialized = JSON.stringify<T>(JSON.parse<T>(JSON.stringify(data)));
43
- if (deserialized != toBe) {
44
- console.log("Expected: " + toBe);
45
- console.log("Actual: " + deserialized);
46
- } else {
47
- console.log("Passed Test")
48
- }
28
+ const player: Player = {
29
+ firstName: "Emmet",
30
+ lastName: "West",
31
+ lastActive: [8, 27, 2022],
32
+ age: 23,
33
+ pos: {
34
+ x: 3.4,
35
+ y: 1.2,
36
+ z: 8.3,
37
+ },
38
+ isVerified: true,
49
39
  }
50
40
 
51
- canSerde<Player>({
52
- firstName: "Emmet",
53
- lastName: "West",
54
- lastActive: [8, 27, 2022],
55
- age: 23,
56
- pos: {
57
- x: 3.4,
58
- y: 1.2,
59
- z: 8.3,
60
- },
61
- isVerified: true,
62
- }, '{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}');
63
- const serializedPlayer = JSON.stringify<Player>(player);
64
- console.log(serializedPlayer);
65
- const parsedPlayer = JSON.parse<Player>(serializedPlayer);
66
- console.log(JSON.stringify(parsedPlayer));
41
+ console.log("Original: " + JSON.stringify(vec));
42
+ //console.log("Revised: " + vec.__JSON_Deserialize('{"x":3,"y":1,"z":8}').__JSON_Serialize());
43
+ console.log("Implemented: " + JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}')));
44
+
45
+ console.log("Original: " + JSON.stringify(player));
46
+ //console.log("Revised: " + vec.__JSON_Deserialize('{"x":3,"y":1,"z":8}').__JSON_Serialize());
47
+ console.log("Implemented: " + JSON.stringify(JSON.parse<Player>('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}')));
48
+
49
+ console.log("Serialized String: " + serializeString('st"ring" w""ith quotes"'));
67
50
 
68
- const serializedVec3 = JSON.stringify(vec);
69
- console.log(serializedVec3);
51
+ bench("New Stringify String", () => {
52
+ blackbox<string>(serializeString(blackbox<string>('st"ring" w""ith quotes"')));
53
+ });
54
+ /*
55
+ // 9,325,755
56
+ bench("Stringify Object (Vec3)", () => {
57
+ blackbox<string>(vec.__JSON_Serialize());
58
+ });
70
59
 
71
- const parsedVec3 = JSON.parse<Vec3>(serializedVec3);
72
- console.log(JSON.stringify(parsedVec3));
60
+ // 17,747,531 -> 55,517,015
61
+ /*bench("New Parse Object (Vec3)", () => {
62
+ blackbox<Vec3>(vec.__JSON_Deserialize(blackbox<string>('{"x":0,"y":0,"z":0}')));
63
+ });
73
64
 
74
- console.log("snip:");
75
- console.log("1234 <-> " + snip_fast<i32>("1234").toString());
76
- console.log("-1234 <-> " + snip_fast<i32>("-1234").toString());
77
- console.log("12340 <-> " + snip_fast<i32>("1234e1").toString());
78
- console.log("123400 <-> " + snip_fast<i32>("1234e2").toString());
79
- console.log("1234000 <-> " + snip_fast<i32>("1234e3").toString());
80
- console.log("12 <-> " + snip_fast<i32>("123e-1").toString());
81
- console.log("123 <-> " + snip_fast<i32>("123").toString());
82
- console.log("-12340 <-> " + snip_fast<i32>("-1234e1").toString());
83
- console.log("-1234500 <-> " + snip_fast<i32>("-12345e2").toString());
84
- console.log("-123456000 <-> " + snip_fast<i32>("-123456e3").toString());
85
- console.log("-12 <-> " + snip_fast<i32>("-123e-1").toString());
86
- console.log("-123 <-> " + snip_fast<i32>("-123").toString());
87
- console.log(snip_fast<i32>("1000").toString());
88
- console.log(snip_fast<i32>("-1000").toString());
89
- console.log(JSON.stringify([[1, 2, 3, 4, 5], [5, 4, 3, 2, 1]]));
65
+ // 17,747,531
66
+ bench("Old Parse Object (Vec3)", () => {
67
+ blackbox<Vec3>(JSON.parse<Vec3>(blackbox<string>('{"x":3.4,"y":1.2,"z":8.3}')));
68
+ });*/