Skip to content

Instantly share code, notes, and snippets.

@IAmJSD
Last active January 28, 2025 15:35
Show Gist options
  • Save IAmJSD/570076df80919063e1f1f9eaa2103423 to your computer and use it in GitHub Desktop.
Save IAmJSD/570076df80919063e1f1f9eaa2103423 to your computer and use it in GitHub Desktop.
import { Pool } from "pg";
import postgres from "postgres";
const pool = new Pool({ connectionString: process.env.DATABASE_URL! });
const pgJs = postgres(process.env.DATABASE_URL!);
async function average(fn: () => Promise<any>) {
const times: number[] = [];
for (let i = 0; i < 10; i++) {
const t1 = performance.now();
await fn();
const t2 = performance.now();
times.push(t2 - t1);
// @ts-ignore: Use Bun.gc() if Bun is available, otherwise use gc()
"Bun" in globalThis ? Bun.gc() : global.gc();
}
return times.reduce((a, b) => a + b, 0) / times.length;
}
async function bunRun100kSelectQueries() {
if (!("Bun" in globalThis)) {
console.log("Bun is not available");
return;
}
console.log("Running Bun 100k select");
const avg = await average(async () => {
for (let i = 0; i < 100000; i++) {
const _ = await Bun.sql`SELECT 1`;
}
});
console.log(`Bun 100k select took ${avg}ms`);
}
async function pgRun100kSelectQueries() {
console.log("Running pg 100k select");
const avg = await average(async () => {
for (let i = 0; i < 100000; i++) {
const _ = await pool.query("SELECT 1");
}
});
console.log(`pg 100k select took ${avg}ms`);
}
async function pgJsRun100kSelectQueries() {
console.log("Running pg-js 100k select");
const avg = await average(async () => {
for (let i = 0; i < 100000; i++) {
const _ = await pgJs`SELECT 1`;
}
});
console.log(`pg-js 100k select took ${avg}ms`);
}
async function testRps(fn: () => Promise<any>) {
const startTime = performance.now();
let endTime = 0;
let doneCount = 0;
for (let i = 0; i < 15_000; i++) {
fn().then(() => {
endTime = performance.now();
doneCount++;
});
}
while (doneCount < 15_000) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
// Use the start time and end time to calculate the rps
const rps = Math.round(15_000 / ((endTime - startTime) / 1000));
// @ts-ignore: Bun.gc() is not typed
"Bun" in globalThis ? Bun.gc() : global.gc();
return rps;
}
async function testStaticRpsBun() {
if (!("Bun" in globalThis)) {
console.log("Bun is not available");
return;
}
console.log("Running Bun static rps");
const rps = await testRps(async () => {
const _ = await Bun.sql`SELECT 1`;
});
console.log(`Bun static rps: ${rps}`);
}
async function testTemplateRpsBun() {
if (!("Bun" in globalThis)) {
console.log("Bun is not available");
return;
}
console.log("Running Bun template rps");
const rps = await testRps(async () => {
const _ = await Bun.sql`SELECT ${Math.random()}`;
});
console.log(`Bun template rps: ${rps}`);
}
async function testStaticRpsPg() {
console.log("Running pg static rps");
const rps = await testRps(async () => {
const _ = await pool.query("SELECT 1");
});
console.log(`pg static rps: ${rps}`);
}
async function testTemplateRpsPg() {
console.log("Running pg template rps");
const rps = await testRps(async () => {
const _ = await pool.query("SELECT $1", [Math.random()]);
});
console.log(`pg template rps: ${rps}`);
}
async function testStaticRpsPgJs() {
console.log("Running pg-js static rps");
const rps = await testRps(async () => {
const _ = (await pgJs`SELECT 1`.execute())[0];
});
console.log(`pg-js static rps: ${rps}`);
}
async function testTemplateRpsPgJs() {
console.log("Running pg-js rps");
const rps = await testRps(async () => {
const _ = (await pgJs`SELECT ${Math.random()}`.execute())[0];
});
console.log(`pg-js rps: ${rps}`);
}
(async () => {
await testStaticRpsBun();
await testStaticRpsPg();
await testStaticRpsPgJs();
await testTemplateRpsBun();
await testTemplateRpsPg();
await testTemplateRpsPgJs();
await bunRun100kSelectQueries();
await pgRun100kSelectQueries();
await pgJsRun100kSelectQueries();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment