Skip to content

Commit

Permalink
faster scientific notation parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Jun 10, 2024
1 parent d05d107 commit 53c444f
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 14 deletions.
3 changes: 1 addition & 2 deletions assembly/deserialize/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { snip_fast } from "../src/util";

// @ts-ignore: Decorator
@inline export function deserializeNumber<T>(data: string, start: i32 = 0, end: i32 = 0): T {
end = end || data.length - 1;
if (isInteger<T>()) {
// @ts-ignore
return snip_fast<T>(data.slice(start, end));
return snip_fast<T>(data, start, end || data.length << 1);
}
// @ts-ignore
const type: T = 0;
Expand Down
9 changes: 6 additions & 3 deletions assembly/deserialize/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import { Sink } from "../src/sink";
let result = Sink.withCapacity(end - start - 1);
const firstChar = unsafeCharCodeAt(data, start);
const lastChar = unsafeCharCodeAt(data, end);

if (firstChar !== quoteCode || lastChar !== quoteCode) {
throw new Error(`Expected string to start and end with ", but got ${data.slice(0, 100)} instead!`);
}

let last = start + 1;
for (let i = last; i < end; i++) {
if (unsafeCharCodeAt(data, i) !== backSlashCode) {
continue;
}
if (unsafeCharCodeAt(data, i) !== backSlashCode) continue;

const char = unsafeCharCodeAt(data, ++i);
result.write(data, last, i - 1);
switch (char) {
Expand Down Expand Up @@ -87,8 +88,10 @@ import { Sink } from "../src/sink";
}
}
}

if (end > last) {
result.write(data, last, end);
}

return result.toString();
}
2 changes: 1 addition & 1 deletion assembly/deserialize/unknown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { deserializeString } from "./string";
return Result.Ok<JSON.Value, string>(JSON.Value.from<boolean>(true));
} else if (
firstChar === fCode
&& load<u64>(changetype<usize>(data), 2) === 28429466576093281 // "alse"
&& load<u64>(changetype<usize>(data), 2) === 28429466576093281 // "false"
) {
return Result.Ok<JSON.Value, string>(JSON.Value.from<boolean>(false));
}
Expand Down
11 changes: 6 additions & 5 deletions assembly/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ import { Product } from "../product";
* @param str - Any number. Can include scientific notation.
*/
// @ts-ignore: Decorator
@inline export function snip_fast<T extends number>(str: string, len: u32 = 0, offset: u32 = 0): T {
@inline export function snip_fast<T extends number>(str: string, start: u32 = 0, end: u32 = str.length << 1): T {
let val: T = 0 as T;
const len: u32 = end - start;
if (isSigned<T>()) {
const firstChar: u32 = load<u16>(changetype<usize>(str));
if (firstChar === 48) return 0 as T;
const isNegative = firstChar === 45; // Check if the number is negative
let val: T = 0 as T;
if (len == 0) len = u32(str.length << 1);
if (isNegative) {
offset += 2;
let offset: u32 = 2;
if (len >= 4) {
// 32-bit route
for (; offset < (len - 3); offset += 4) {
Expand Down Expand Up @@ -146,6 +146,7 @@ import { Product } from "../product";
}
return -val as T;
} else {
let offset: u32 = 0;
if (len >= 4) {
// Duplet 16 bit lane load
for (; offset < (len - 3); offset += 4) {
Expand Down Expand Up @@ -198,7 +199,7 @@ import { Product } from "../product";
const firstChar: u32 = load<u16>(changetype<usize>(str));
if (firstChar === 48) return 0 as T;
let val: T = 0 as T;
if (len == 0) len = u32(str.length << 1);
let offset: u32 = 0;
if (len >= 4) {
// Duplet 16 bit lane load
for (; offset < (len - 3); offset += 4) {
Expand Down
12 changes: 9 additions & 3 deletions assembly/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { deserializeArray } from "./deserialize/array/array";
import { deserializeBooleanArray } from "./deserialize/array/boolean";
import { deserializeNumberArray } from "./deserialize/array/number";
import { deserializeStringArray } from "./deserialize/array/string";
import { deserializeNumber } from "./deserialize/number";
import { utoa32 } from "./serialize/integer";
import { Sink } from "./src/sink";
import { describe, expect } from "as-test/assembly";
/*
import { __atoi_fast } from "./src/util";

describe("Serialize String", () => {
expect(JSON.serialize("hello world").toString()).toBe("\"hello world\"");
});
Expand Down Expand Up @@ -128,7 +130,11 @@ map.set("z", JSON.Value.from<f64>(-5.6));
describe("Serialize Maps", () => {
expect(JSON.serialize(map).toString()).toBe("{\"x\":3.4,\"y\":1.2,\"z\":-5.6}");
});
*/

describe("Deserialize Number", () => {
expect(JSON.serialize(deserializeNumber<i32>("1234e3")).toString()).toBe("1234000");
})
/*
describe("Deserialize String[]", () => {
expect(JSON.serialize(deserializeStringArray("[\"hello\",\"world\"]")).toString()).toBe("[\"hello\",\"world\"]");
Expand All @@ -144,4 +150,4 @@ describe("Deserialize Boolean[]", () => {
describe("Deserialize [][]", () => {
deserializeArray<JSON.Value[]>("[[[]],[[[]]]]")
});
});*/

0 comments on commit 53c444f

Please sign in to comment.