Skip to content

Commit

Permalink
Performance improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
pouya-eghbali committed Nov 18, 2024
1 parent 13770d1 commit 2e9aab6
Show file tree
Hide file tree
Showing 16 changed files with 1,484 additions and 182 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ isolate-*
*.ignore
coverage
dist
.yarn
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
29 changes: 0 additions & 29 deletions package-lock.json

This file was deleted.

13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@
"scripts": {
"build": "tsc",
"lint": "tslint -p tsconfig.json",
"prepublishOnly": "npm run build"
"prepublishOnly": "yarn build",
"benchmark": "yarn build && yarn node dist/benchmark/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@faker-js/faker": "^9.2.0",
"@types/node": "^22.9.0",
"cbor-x": "^1.6.0",
"msgpackr": "^1.11.2",
"sializer": "0",
"tinybench": "^3.0.6",
"typescript": "^5.4.3"
}
},
"packageManager": "yarn@4.4.1",
"type": "module"
}
25 changes: 25 additions & 0 deletions src/benchmark/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Bench } from "tinybench";
import { siaFiveThousandUsers } from "./tests/sia.js";
import { jsonFiveThousandUsers } from "./tests/json.js";
import { cborFiveThousandUsers } from "./tests/cbor.js";
import { siaOneFiveThousandUsers } from "./tests/sia-v1.js";
import { msgpackrFiveThousandUsers } from "./tests/msgpackr.js";

const bench = new Bench({ name: "serialization", time: 60 * 1000 });

bench.add("JSON", () => jsonFiveThousandUsers());
bench.add("Sializer", () => siaFiveThousandUsers());
bench.add("Sializer (v1)", () => siaOneFiveThousandUsers());
bench.add("CBOR-X", () => cborFiveThousandUsers());
bench.add("MsgPackr", () => msgpackrFiveThousandUsers());

console.log(`Running ${bench.name} benchmark...`);
await bench.run();

console.table(bench.table());

console.log("Sia file size:", siaFiveThousandUsers().length);
console.log("Sia v1 file size:", siaOneFiveThousandUsers().length);
console.log("JSON file size:", jsonFiveThousandUsers().length);
console.log("MsgPackr file size:", cborFiveThousandUsers().length);
console.log("CBOR-X file size:", msgpackrFiveThousandUsers().length);
4 changes: 4 additions & 0 deletions src/benchmark/tests/cbor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { fiveThousandUsers } from "./common.js";
import { encode } from "cbor-x";

export const cborFiveThousandUsers = () => encode(fiveThousandUsers);
21 changes: 21 additions & 0 deletions src/benchmark/tests/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { faker } from "@faker-js/faker";

export function createRandomUser() {
return {
userId: faker.string.uuid(),
username: faker.internet.username(),
email: faker.internet.email(),
avatar: faker.image.avatar(),
password: faker.internet.password(),
birthdate: faker.date.birthdate(),
registeredAt: faker.date.past(),
};
}

export const fiveUsers = faker.helpers.multiple(createRandomUser, {
count: 5,
});

export const fiveThousandUsers = faker.helpers.multiple(createRandomUser, {
count: 5_000,
});
4 changes: 4 additions & 0 deletions src/benchmark/tests/json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { fiveThousandUsers } from "./common.js";

export const jsonFiveThousandUsers = () =>
Buffer.from(JSON.stringify(fiveThousandUsers));
4 changes: 4 additions & 0 deletions src/benchmark/tests/msgpackr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { fiveThousandUsers } from "./common.js";
import { pack } from "msgpackr";

export const msgpackrFiveThousandUsers = () => pack(fiveThousandUsers);
4 changes: 4 additions & 0 deletions src/benchmark/tests/sia-v1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { fiveThousandUsers } from "./common.js";
import { sia } from "sializer";

export const siaOneFiveThousandUsers = () => sia(fiveThousandUsers);
18 changes: 18 additions & 0 deletions src/benchmark/tests/sia.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { fiveThousandUsers } from "./common.js";
import { Sia } from "../../index.js";

const sia = new Sia();

export const siaFiveThousandUsers = () =>
sia
.seek(0)
.addArray16(fiveThousandUsers, (sia, user) => {
sia.addString8(user.userId);
sia.addString8(user.username);
sia.addString8(user.email);
sia.addString8(user.avatar);
sia.addString8(user.password);
sia.addUInt32(user.birthdate.valueOf());
sia.addUInt32(user.registeredAt.valueOf());
})
.toUint8ArrayReference();
61 changes: 61 additions & 0 deletions src/buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
export class Buffer {
public size: number;
public content: Uint8Array;
public offset: number;
public dataView: DataView;

constructor(uint8Array: Uint8Array) {
this.size = uint8Array.length;
this.content = uint8Array;
this.offset = 0;
this.dataView = new DataView(uint8Array.buffer);
}

static new(size: number = 32 * 1024 * 1024) {
return new Buffer(new Uint8Array(size));
}

seek(offset: number) {
this.offset = offset;
}

skip(count: number) {
this.offset += count;
}

add(data: Uint8Array) {
if (this.offset + data.length > this.size) {
throw new Error("Buffer overflow");
}
this.content.set(data, this.offset);
this.offset += data.length;
}

addOne(data: number) {
if (this.offset + 1 > this.size) {
throw new Error("Buffer overflow");
}
this.content[this.offset] = data;
this.offset++;
}

toUint8Array() {
return this.content.slice(0, this.offset);
}

toUint8ArrayReference() {
return this.content.subarray(0, this.offset);
}

slice(start: number, end: number) {
return this.content.slice(start, end);
}

get(offset: number) {
return this.content[offset];
}

get length() {
return this.size;
}
}
Loading

0 comments on commit 2e9aab6

Please sign in to comment.