Skip to content

Instantly share code, notes, and snippets.

@zxcodes
Last active January 24, 2025 02:46
Show Gist options
  • Select an option

  • Save zxcodes/3b55debb71a7300c472d8b00bd3cc58e to your computer and use it in GitHub Desktop.

Select an option

Save zxcodes/3b55debb71a7300c472d8b00bd3cc58e to your computer and use it in GitHub Desktop.
Promise Perf.
const MAX_TEST_RUNS = 10;
/**
* A typical DB response might look or might not look like this.
* This object size and complexity is intentional.
*/
const response = {
id: Math.random(),
name: `Complex Object ${Math.random().toString()}`,
details: {
description: "This is a complex object with many properties",
createdAt: new Date(),
updatedAt: new Date(),
attributes: {
color: "blue",
size: "large",
weight: "heavy",
dimensions: {
length: 100 + Math.random(),
width: 50 + Math.random(),
height: 75 + Math.random(),
},
materials: ["metal", "plastic", "wood"],
tags: ["tag1", "tag2", "tag3"],
status: "active",
metadata: {
version: "1.0.0",
author: "Author Name",
license: "MIT",
links: [
{ type: "website", url: "https://example.com" },
{ type: "repository", url: "https://github.com/example" },
],
},
},
},
relationships: {
parent: { id: 0, name: "Parent Object" },
children: [
{ id: 2, name: "Child Object 1" },
{ id: 3, name: "Child Object 2" },
{ id: 4, name: "Child Object 3" },
],
related: [
{ id: 5, name: "Related Object 1" },
{ id: 6, name: "Related Object 2" },
],
},
history: [
{ event: "created", timestamp: new Date(), by: "user1" },
{ event: "updated", timestamp: new Date(), by: "user2" },
{ event: "modified", timestamp: new Date(), by: "user3" },
],
config: {
settings: {
option1: true,
option2: false,
option3: "default",
thresholds: {
min: 10,
max: 100,
default: 50,
},
},
permissions: {
read: ["user1", "user2"],
write: ["user2"],
execute: ["user3"],
},
},
statistics: {
views: 1024,
likes: 512,
shares: 256,
comments: 128,
ratings: {
average: 4.5,
total: 50,
breakdown: {
"1_star": 5,
"2_star": 3,
"3_star": 10,
"4_star": 12,
"5_star": 20,
},
},
},
newData: {
id: Math.random(),
name: `Complex Object ${Math.random().toString()}`,
details: {
description: "This is a complex object with many properties",
createdAt: new Date(),
updatedAt: new Date(),
attributes: {
color: "blue",
size: "large",
weight: "heavy",
dimensions: {
length: 100 + Math.random(),
width: 50 + Math.random(),
height: 75 + Math.random(),
},
materials: ["metal", "plastic", "wood"],
tags: ["tag1", "tag2", "tag3"],
status: "active",
metadata: {
version: "1.0.0",
author: "Author Name",
license: "MIT",
links: [
{ type: "website", url: "https://example.com" },
{ type: "repository", url: "https://github.com/example" },
],
},
},
},
relationships: {
parent: { id: 0, name: "Parent Object" },
children: [
{ id: 2, name: "Child Object 1" },
{ id: 3, name: "Child Object 2" },
{ id: 4, name: "Child Object 3" },
],
related: [
{ id: 5, name: "Related Object 1" },
{ id: 6, name: "Related Object 2" },
],
},
history: [
{ event: "created", timestamp: new Date(), by: "user1" },
{ event: "updated", timestamp: new Date(), by: "user2" },
{ event: "modified", timestamp: new Date(), by: "user3" },
],
config: {
settings: {
option1: true,
option2: false,
option3: "default",
thresholds: {
min: 10,
max: 100,
default: 50,
},
},
permissions: {
read: ["user1", "user2"],
write: ["user2"],
execute: ["user3"],
},
},
statistics: {
views: 1024,
likes: 512,
shares: 256,
comments: 128,
ratings: {
average: 4.5,
total: 50,
breakdown: {
"1_star": 5,
"2_star": 3,
"3_star": 10,
"4_star": 12,
"5_star": 20,
},
},
},
},
};
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
/**
* Each on this could be a DB query. We're also adding an artificial delay
* to simulate network condition or the query latency.
*
* Each of this query resolves the same object in different ways
* to mimic different DB query responses.
*/
const q1 = async () => {
await delay(100);
return await Promise.resolve({ response });
};
const q2 = async () => {
await delay(200);
return await Promise.resolve([response, [{ response }], [{ ...response }]]);
};
const q3 = async () => {
await delay(300);
return await Promise.resolve([
[response, response, { response, ...response }],
]);
};
const q4 = async () => {
await delay(400);
return await Promise.resolve([
[[{ response }], [{ response }], [{ response }]],
]);
};
// Helper to get the Start and End time of an operation.
const getComputeTime = async (label, callback) => {
if (!label || !callback) throw new Error("Missing arguments.");
console.time(label);
await callback();
console.timeEnd(label);
};
const runTests = async () => {
for (let i = 0; i < MAX_TEST_RUNS; i++) {
console.log(`Run ${i + 1}:`);
await getComputeTime("Parallel", async () => {
await Promise.allSettled([q1(), q2(), q3(), q4()]);
});
await getComputeTime("Sequential", async () => {
await q1();
await q2();
await q3();
await q4();
});
}
};
runTests();
const MAX_TEST_RUNS = 10;
/**
* A typical DB response might look or might not look like this.
* This object size and complexity is intentional.
*/
const response = {
id: Math.random(),
name: `Complex Object ${Math.random().toString()}`,
details: {
description: "This is a complex object with many properties",
createdAt: new Date(),
updatedAt: new Date(),
attributes: {
color: "blue",
size: "large",
weight: "heavy",
dimensions: {
length: 100 + Math.random(),
width: 50 + Math.random(),
height: 75 + Math.random(),
},
materials: ["metal", "plastic", "wood"],
tags: ["tag1", "tag2", "tag3"],
status: "active",
metadata: {
version: "1.0.0",
author: "Author Name",
license: "MIT",
links: [
{ type: "website", url: "https://example.com" },
{ type: "repository", url: "https://github.com/example" },
],
},
},
},
relationships: {
parent: { id: 0, name: "Parent Object" },
children: [
{ id: 2, name: "Child Object 1" },
{ id: 3, name: "Child Object 2" },
{ id: 4, name: "Child Object 3" },
],
related: [
{ id: 5, name: "Related Object 1" },
{ id: 6, name: "Related Object 2" },
],
},
history: [
{ event: "created", timestamp: new Date(), by: "user1" },
{ event: "updated", timestamp: new Date(), by: "user2" },
{ event: "modified", timestamp: new Date(), by: "user3" },
],
config: {
settings: {
option1: true,
option2: false,
option3: "default",
thresholds: {
min: 10,
max: 100,
default: 50,
},
},
permissions: {
read: ["user1", "user2"],
write: ["user2"],
execute: ["user3"],
},
},
statistics: {
views: 1024,
likes: 512,
shares: 256,
comments: 128,
ratings: {
average: 4.5,
total: 50,
breakdown: {
"1_star": 5,
"2_star": 3,
"3_star": 10,
"4_star": 12,
"5_star": 20,
},
},
},
newData: {
id: Math.random(),
name: `Complex Object ${Math.random().toString()}`,
details: {
description: "This is a complex object with many properties",
createdAt: new Date(),
updatedAt: new Date(),
attributes: {
color: "blue",
size: "large",
weight: "heavy",
dimensions: {
length: 100 + Math.random(),
width: 50 + Math.random(),
height: 75 + Math.random(),
},
materials: ["metal", "plastic", "wood"],
tags: ["tag1", "tag2", "tag3"],
status: "active",
metadata: {
version: "1.0.0",
author: "Author Name",
license: "MIT",
links: [
{ type: "website", url: "https://example.com" },
{ type: "repository", url: "https://github.com/example" },
],
},
},
},
relationships: {
parent: { id: 0, name: "Parent Object" },
children: [
{ id: 2, name: "Child Object 1" },
{ id: 3, name: "Child Object 2" },
{ id: 4, name: "Child Object 3" },
],
related: [
{ id: 5, name: "Related Object 1" },
{ id: 6, name: "Related Object 2" },
],
},
history: [
{ event: "created", timestamp: new Date(), by: "user1" },
{ event: "updated", timestamp: new Date(), by: "user2" },
{ event: "modified", timestamp: new Date(), by: "user3" },
],
config: {
settings: {
option1: true,
option2: false,
option3: "default",
thresholds: {
min: 10,
max: 100,
default: 50,
},
},
permissions: {
read: ["user1", "user2"],
write: ["user2"],
execute: ["user3"],
},
},
statistics: {
views: 1024,
likes: 512,
shares: 256,
comments: 128,
ratings: {
average: 4.5,
total: 50,
breakdown: {
"1_star": 5,
"2_star": 3,
"3_star": 10,
"4_star": 12,
"5_star": 20,
},
},
},
},
};
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
/**
* Each on this could be a DB query. We're also adding an artificial delay
* to simulate network condition or the query latency.
*
* Each of this query resolves the same object in different ways
* to mimic different DB query responses.
*/
const q1 = async () => {
await delay(100);
return Promise.resolve({ response });
};
const q2 = async () => {
await delay(200);
return Promise.resolve([response, [{ response }], [{ ...response }]]);
};
const q3 = async () => {
await delay(300);
return Promise.resolve([[response, response, { response, ...response }]]);
};
const q4 = async () => {
await delay(400);
return Promise.resolve([[[{ response }], [{ response }], [{ response }]]]);
};
// Helper to get the Start and End time of an operation.
const getComputeTime = async (label: string, callback: () => Promise<void>) => {
if (!label || !callback) throw new Error("Missing arguments.");
console.time(label);
await callback();
console.timeEnd(label);
};
const runTests = async () => {
for (let i = 0; i < MAX_TEST_RUNS; i++) {
console.log(`Run ${i + 1}:`);
await getComputeTime("Parallel", async () => {
await Promise.allSettled([q1(), q2(), q3(), q4()]);
});
await getComputeTime("Sequential", async () => {
await q1();
await q2();
await q3();
await q4();
});
}
};
runTests();

Running the bench:

bun bench.ts

If you don't have bun:

node bench.js 

(Or paste the bench.js file in your browser's console)

Run 1

  • [402.22ms] Parallel
  • [1007.86ms] Sequential

Run 2

  • [400.90ms] Parallel
  • [1005.21ms] Sequential

Run 3

  • [401.36ms] Parallel
  • [1005.22ms] Sequential

Run 4

  • [401.25ms] Parallel
  • [1004.59ms] Sequential

Run 5

  • [401.59ms] Parallel
  • [1007.86ms] Sequential

Run 6

  • [401.38ms] Parallel
  • [1006.59ms] Sequential

Run 7

  • [401.37ms] Parallel
  • [1007.97ms] Sequential

Run 8

  • [401.31ms] Parallel
  • [1004.69ms] Sequential

Run 9

  • [401.43ms] Parallel
  • [1006.31ms] Sequential

Run 10

  • [403.13ms] Parallel
  • [1005.93ms] Sequential
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment