You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

json-as

Package Overview
Dependencies
Maintainers
1
Versions
195
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-as - npm Package Compare versions

Comparing version

to
1.1.20

bench.ts

16

assembly/__benches__/abc.bench.ts

@@ -8,2 +8,3 @@ import { JSON } from "..";

const blackBoxArea = memory.data(64);
expect(JSON.stringify(v1)).toBe(v2);

@@ -14,5 +15,6 @@

() => {
inline.always(JSON.stringify(v1));
blackbox(inline.always(JSON.stringify(blackbox(v1))));
},
64_000_00,
24_000_00,
v1.length << 1,
);

@@ -23,5 +25,11 @@

() => {
inline.always(JSON.parse<string>(v2));
blackbox(inline.always(JSON.parse<string>(blackbox(v2))));
},
64_000_00,
24_000_00,
v2.length << 1,
);
function blackbox<T>(value: T): T {
store<T>(blackBoxArea, value);
return load<T>(blackBoxArea);
}

@@ -1,3 +0,4 @@

export function bench(description: string, routine: () => void, ops: u64 = 1_000_000): void {
export function bench(description: string, routine: () => void, ops: u64 = 1_000_000, bytesPerOp: u64 = 0): void {
console.log(" - Benchmarking " + description);
let warmup = ops / 10;

@@ -7,13 +8,24 @@ while (--warmup) {

}
const start = Date.now();
const start = performance.now();
let count = ops;
while (count != 0) {
while (count--) {
routine();
count--;
}
const elapsed = Date.now() - start;
let opsPerSecond = (ops * 1000) / elapsed;
const end = performance.now();
const elapsed = Math.max(1, end - start);
console.log(` Completed benchmark in ${formatNumber(elapsed)}ms at ${formatNumber(opsPerSecond)} ops/s\n`);
const opsPerSecond = f64(ops * 1000) / elapsed;
let log = ` Completed benchmark in ${formatNumber(u64(Math.round(elapsed)))}ms at ${formatNumber(u64(Math.round(opsPerSecond)))} ops/s`;
if (bytesPerOp > 0) {
const totalBytes = bytesPerOp * ops;
const mbPerSec = f64(totalBytes) / (elapsed / 1000) / (1000 * 1000);
log += ` @ ${formatNumber(u64(Math.round(mbPerSec)))}MB/s`;
}
console.log(log + "\n");
}

@@ -20,0 +32,0 @@

@@ -30,2 +30,4 @@ /// <reference path="./index.d.ts" />

import { deserializeRaw } from "./deserialize/simple/raw";
import { serializeString_SIMD } from "./serialize/simd/string";
// import { deserializeString_SIMD } from "./deserialize/simd/string";

@@ -116,7 +118,7 @@ /**

// }
// if (ASC_FEATURE_SIMD) {
// serializeString_SIMD(data as string);
// } else {
serializeString(data as string);
// }
if (ASC_FEATURE_SIMD) {
serializeString_SIMD(data as string);
} else {
serializeString(data as string);
}
return bs.out<string>();

@@ -184,3 +186,3 @@ // @ts-ignore: Supplied by transform

// if (ASC_FEATURE_SIMD) {
// // @ts-ignore
// // @ts-ignore
// return changetype<string>(deserializeString_SIMD(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>())));

@@ -432,3 +434,3 @@ // } else {

constructor() {}
constructor() { }

@@ -549,3 +551,7 @@ // @ts-ignore: decorator

} else if (isString<nonnull<T>>()) {
serializeString(src as string);
if (ASC_FEATURE_SIMD) {
serializeString_SIMD(src as string);
} else {
serializeString(src as string);
}
// @ts-ignore: Supplied by transform

@@ -722,8 +728,8 @@ } else if (isDefined(src.__SERIALIZE_CUSTOM)) {

// }
// if (ASC_FEATURE_SIMD) {
// serializeString_SIMD(data as string);
// } else {
bs.saveState();
serializeString(data as string);
// }
if (ASC_FEATURE_SIMD) {
serializeString_SIMD(data as string);
} else {
bs.saveState();
serializeString(data as string);
}
return bs.cpyOut<string>();

@@ -730,0 +736,0 @@ // @ts-ignore: Supplied by transform

@@ -6,2 +6,4 @@ import { bs } from "../../../lib/as-bs";

const U00_MARKER = 13511005048209500;
/**

@@ -17,3 +19,2 @@ * Serializes strings into their JSON counterparts using SIMD operations

const SPLAT_32 = i16x8.splat(32); /* [ESC] */
const SPLAT_0 = i16x8.splat(0); /* 0 */

@@ -25,3 +26,3 @@ const srcSize = bytes(src);

bs.proposeSize(srcSize + 4);
bs.proposeSize(srcSize + 40);

@@ -33,2 +34,3 @@ store<u8>(changetype<usize>(bs.offset), 34); /* " */

const block = v128.load(srcStart);
v128.store(bs.offset, block);

@@ -45,12 +47,10 @@

const lane_index = ctz(mask) << 1;
const dst_offset = bs.offset + lane_index;
const src_offset = srcStart + lane_index;
const code = load<u16>(src_offset) << 2;
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + code);
mask &= mask - 1;
if ((escaped & 0xffff) != BACK_SLASH) {
bs.growSize(10);
store<u64>(dst_offset, 13511005048209500);
const dst_offset = bs.offset + lane_index;
store<u64>(dst_offset, U00_MARKER);
store<u32>(dst_offset, escaped, 8);

@@ -61,2 +61,3 @@ v128.store(dst_offset, v128.load(src_offset, 2), 12);

bs.growSize(2);
const dst_offset = bs.offset + lane_index;
store<u32>(dst_offset, escaped);

@@ -72,97 +73,9 @@ v128.store(dst_offset, v128.load(src_offset, 2), 4);

const rem = srcEnd - srcStart;
if (rem & 8) {
const block = v128.load64_zero(srcStart);
v128.store64_lane(bs.offset, block, 0);
const backslash_indices = i16x8.eq(block, SPLAT_92);
const quote_indices = i16x8.eq(block, SPLAT_34);
const escape_indices = i16x8.lt_u(block, SPLAT_32);
const zero_indices = i16x8.eq(block, SPLAT_0);
const sieve = v128.and(v128.or(v128.or(backslash_indices, quote_indices), escape_indices), v128.not(zero_indices));
let mask = i16x8.bitmask(sieve);
while (mask != 0) {
let lane_index = ctz(mask) << 1;
const dst_offset = bs.offset + lane_index;
const src_offset = srcStart + lane_index;
const code = load<u16>(src_offset) << 2;
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + code);
mask &= mask - 1;
if ((escaped & 0xffff) != BACK_SLASH) {
bs.growSize(10);
store<u64>(dst_offset, 13511005048209500);
store<u32>(dst_offset, escaped, 8);
while (lane_index < 6) {
store<u8>(bs.offset + lane_index, load<u8>(srcStart + lane_index, 2), 12);
lane_index += 2;
}
bs.offset += 10;
} else {
bs.growSize(2);
store<u32>(dst_offset, escaped);
while (lane_index < 6) {
store<u8>(bs.offset + lane_index, load<u8>(srcStart + lane_index, 2), 4);
lane_index += 2;
}
bs.offset += 2;
}
}
bs.offset += 8;
srcStart += 8;
}
if (rem & 4) {
const block = load<u32>(srcStart);
const codeA = block & 0xffff;
const codeB = (block >> 16) & 0xffff;
if (codeA == 92 || codeA == 34 || codeA < 32) {
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeA << 2));
if ((escaped & 0xffff) != BACK_SLASH) {
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);
store<u32>(bs.offset, escaped, 8);
bs.offset += 12;
} else {
bs.growSize(2);
store<u32>(bs.offset, escaped);
bs.offset += 4;
}
} else {
store<u16>(bs.offset, codeA);
bs.offset += 2;
}
if (codeB == 92 || codeB == 34 || codeB < 32) {
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeB << 2));
if ((escaped & 0xffff) != BACK_SLASH) {
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);
store<u32>(bs.offset, escaped, 8);
bs.offset += 12;
} else {
bs.growSize(2);
store<u32>(bs.offset, escaped);
bs.offset += 4;
}
} else {
store<u16>(bs.offset, codeB);
bs.offset += 2;
}
srcStart += 4;
}
if (rem & 2) {
while (srcStart <= srcEnd - 2) {
const code = load<u16>(srcStart);
if (code == 92 || code == 34 || code < 32) {
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
if ((escaped & 0xffff) != BACK_SLASH) {
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);
store<u64>(bs.offset, U00_MARKER);
store<u32>(bs.offset, escaped, 8);

@@ -179,2 +92,3 @@ bs.offset += 12;

}
srcStart += 2;
}

@@ -181,0 +95,0 @@

import { JSON } from "../assembly/index";
import { bs } from "../lib/as-bs";
@json

@@ -27,2 +28,3 @@ class Vec3 {

@inline

@@ -208,2 +210,3 @@ __INITIALIZE(): this {

@json

@@ -217,2 +220,3 @@ class Player {

@omitif((self: this): boolean => self.age < 18)

@@ -266,2 +270,3 @@ age!: i32;

@inline

@@ -268,0 +273,0 @@ __INITIALIZE(): this {

@@ -9,5 +9,6 @@ import { bench } from "./lib/bench.js";

() => {
JSON.stringify(v1);
blackbox(JSON.stringify(blackbox(v1)));
},
64_000_00,
v1.length << 1,
);

@@ -18,5 +19,11 @@

() => {
JSON.parse(v2);
blackbox(JSON.parse(blackbox(v2)));
},
64_000_00,
v2.length << 1,
);
function blackbox<T>(value: T): T {
(globalThis as any).__blackhole = value;
return globalThis.__blackhole;
}

@@ -1,27 +0,42 @@

if (typeof console === "undefined") {
console = {
log: print,
error: print,
warn: print,
};
}
export function bench(description: string, routine: () => void, ops: number = 1_000_000, bytesPerOp: number = 0): void {
console.log(" - Benchmarking " + description);
export function bench(description: string, routine: () => void, ops: number = 1_000_000): void {
console.log(" - Benchmarking " + description);
let warmup = ops / 10;
while (--warmup) {
let warmup = Math.floor(ops / 10);
while (warmup-- > 0) {
routine();
}
const start = Date.now();
const start = performance.now();
let count = ops;
while (count !== 0) {
while (count-- > 0) {
routine();
count--;
}
const elapsed = Date.now() - start;
const opsPerSecond = Math.round((ops * 1000) / elapsed);
const format = new Intl.NumberFormat("en-US");
const end = performance.now();
const elapsed = Math.max(1, end - start);
console.log(` Completed benchmark in ${format.format(elapsed)}ms at ${format.format(opsPerSecond)} ops/s\n`);
const opsPerSecond = (ops * 1000) / elapsed;
let log = ` Completed benchmark in ${formatNumber(Math.round(elapsed))}ms at ${formatNumber(Math.round(opsPerSecond))} ops/s`;
if (bytesPerOp > 0) {
const totalBytes = bytesPerOp * ops;
const mbPerSec = totalBytes / (elapsed / 1000) / (1000 * 1000);
log += ` @ ${formatNumber(Math.round(mbPerSec))}MB/s`;
}
console.log(log + "\n");
}
function formatNumber(n: number): string {
let str = n.toString();
let len = str.length;
let result = "";
let commaOffset = len % 3;
for (let i = 0; i < len; i++) {
if (i > 0 && (i - commaOffset) % 3 === 0) result += ",";
result += str.charAt(i);
}
return result;
}

@@ -13,2 +13,3 @@ const bytes = readbuffer("./build/" + arguments[0]);

"Date.now": () => Date.now(),
"performance.now": () => performance.now(),
},

@@ -15,0 +16,0 @@ });

# Change Log
## 2025-07-14 - 1.1.20
- feat: enable SIMD string serialization
## 2025-06-30 - 1.1.19

@@ -4,0 +8,0 @@

{
"name": "json-as",
"version": "1.1.19",
"version": "1.1.20",
"author": "Jairus Tanaka",

@@ -12,6 +12,7 @@ "repository": {

"@assemblyscript/wasi-shim": "^0.1.0",
"@types/node": "^22.15.34",
"@types/node": "^24.0.8",
"assemblyscript": "^0.28.2",
"assemblyscript-prettier": "^3.0.1",
"prettier": "^3.6.2",
"tinybench": "^4.0.1",
"tsx": "^4.20.3",

@@ -18,0 +19,0 @@ "typescript": "^5.8.3"

@@ -9,3 +9,3 @@ <h6 align="center">

</span>
AssemblyScript - v1.1.19
AssemblyScript - v1.1.20
</pre>

@@ -395,3 +395,3 @@ </h6>

| Vector3 Object | 38 bytes | 26,611,226 ops/s | 32,160,804 ops/s | 1,357 MB/s | 1,348 MB/s |
| Alphabet String | 104 bytes | 13,617,021 ops/s | 18,390,804 ops/s | 1,416 MB/s | 1,986 MB/s |
| Alphabet String | 104 bytes | 16,916,886 ops/s | 18,390,804 ops/s | 1,759 MB/s | 1,986 MB/s |
| Small Object | 88 bytes | 24,242,424 ops/s | 12,307,692 ops/s | 2,133 MB/s | 1,083 MB/s |

@@ -406,3 +406,3 @@ | Medium Object | 494 bytes | 4,060,913 ops/s | 1,396,160 ops/s | 2,006 MB/s | 689.7 MB/s |

| Vector3 Object | 38 bytes | 8,791,209 ops/s | 5,369,12 ops/s | 357.4 MB/s | 204.3 MB/s |
| Alphabet String | 104 bytes | 13,793,103 ops/s | 14,746,544 ops/s | 1,416 MB/s | 1,592 MB/s |
| Alphabet String | 104 bytes | 12,830,228 ops/s | 12,140,296 ops/s | 1,334 MB/s | 1,311 MB/s |
| Small Object | 88 bytes | 8,376,963 ops/s | 4,968,944 ops/s | 737.1 MB/s | 437.2 MB/s |

@@ -409,0 +409,0 @@ | Medium Object | 494 bytes | 2,395,210 ops/s | 1,381,693 ops/s | 1,183 MB/s | 682.5 MB/s |

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet