Skip to content

Commit

Permalink
chore: create bench dir
Browse files Browse the repository at this point in the history
  • Loading branch information
hasundue committed Mar 23, 2024
1 parent 1a34c4a commit a0780e4
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 3 deletions.
37 changes: 37 additions & 0 deletions bench/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## Benchmarks

We are still trying to find a fair way to compare the performance of various
Nostr libraries. You should NOT consider the current results reliable.

### Method

WIP

### Results

```sh
cpu: Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz
runtime: deno 1.41.3 (x86_64-unknown-linux-gnu)

file:///home/hasundue/lophus/bench/bench.ts
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------- -----------------------------

# Time to deliver a request to a relay
group subscribe
lophus 52.32 µs/iter 19,111.7 (18.74 µs … 6.17 ms) 52.78 µs 132.19 µs 165.39 µs
nostr_tools 49.33 µs/iter 20,270.0 (38.33 µs … 182.21 µs) 49.32 µs 111.07 µs 133.75 µs

summary
lophus
1.06x slower than nostr_tools

# Time to get an event from a relay
group get an event
lophus 56.3 µs/iter 17,761.7 (27.8 µs … 8.69 ms) 44.75 µs 119.7 µs 166.07 µs
nostr_tools 2.44 ms/iter 409.6 (2.11 ms … 4.93 ms) 2.34 ms 4.4 ms 4.93 ms

summary
lophus
43.36x faster than nostr_tools
```
61 changes: 61 additions & 0 deletions bench/bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { MockWebSocket } from "@lophus/lib/testing";
import { TextNoteComposer } from "@lophus/std/notes";
import { generatePrivateKey, Signer } from "@lophus/std/signs";

const LIBS = ["lophus", "nostr_tools"] as const;

const nsec = generatePrivateKey();
const note = new TextNoteComposer().compose({
content: "bench",
});
const event = new Signer(nsec).sign(note);

for (const lib of LIBS) {
Deno.bench({
name: lib,
baseline: lib === "lophus",
group: "subscribe",
async fn({ start, end }) {
const { setup, subscribe } = await import(`./${lib}.ts`);
const done = (async () => {
const { value: ws } = await MockWebSocket.instances().next();
return new Promise((resolve) =>
ws!.remote.addEventListener("message", resolve)
);
})();
setup({ WebSocket: MockWebSocket });
start();
subscribe();
await done;
end();
},
});

Deno.bench({
name: lib,
baseline: lib === "lophus",
group: "get an event",
async fn({ start, end }) {
const { setup, subscribe, receive } = await import(`./${lib}.ts`);
setup({ WebSocket: MockWebSocket });
const sent = (async () => {
const { value: ws } = await MockWebSocket.instances().next();
return new Promise<void>((resolve) => {
ws!.remote.addEventListener("message", (msg) => {
const [, id] = JSON.parse(msg.data);
ws!.remote.send(
JSON.stringify(["EVENT", id, event]),
);
resolve();
});
});
})();
start();
const sub = await subscribe();
const received = receive(sub);
await sent;
await received;
end();
},
});
}
15 changes: 15 additions & 0 deletions bench/lophus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { NostrEvent, Relay } from "@lophus/nips";
import { BenchContext } from "./types.ts";

export function setup(c: BenchContext) {
globalThis.WebSocket = c.WebSocket;
}

export function subscribe() {
const relay = new Relay("ws://localhost:80");
return relay.subscribe({ kinds: [1] }, { id: "bench" });
}

export async function receive(sub: ReadableStream<NostrEvent<1>>) {
await sub.getReader().read();
}
19 changes: 19 additions & 0 deletions bench/nostr_tools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Relay, useWebSocketImplementation } from "nostr-tools/relay";
import { BenchContext } from "./types.ts";

let received: (() => void) | undefined;

export function setup(c: BenchContext) {
useWebSocketImplementation(c.WebSocket);
}

export async function subscribe() {
const relay = await Relay.connect("ws://localhost:80");
return relay.subscribe([{ kinds: [1] }], { onevent: () => received?.() });
}

export async function receive() {
await new Promise<void>((resolve) => {
received = resolve;
});
}
3 changes: 3 additions & 0 deletions bench/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface BenchContext {
WebSocket: typeof WebSocket;
}
3 changes: 2 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"@lophus/std/watch": "./std/watch.ts",
"@std/assert": "jsr:@std/assert@^0.219.1",
"@std/streams": "jsr:@std/streams@^0.219.1",
"@std/testing": "jsr:@std/testing@^0.219.1"
"@std/testing": "jsr:@std/testing@^0.219.1",
"nostr-tools": "npm:[email protected]"
},
"tasks": {
"build": "mkdir -p ./dist && deno run -A ./bin/bundle.ts",
Expand Down
65 changes: 63 additions & 2 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a0780e4

Please sign in to comment.