Skip to content

Commit b2d9163

Browse files
committed
feat: Create benchmark
1 parent 3831f3a commit b2d9163

11 files changed

Lines changed: 796 additions & 11 deletions

File tree

bench/browser-bench/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

bench/browser-bench/index.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>@wbe/debug vs debug - Benchmark</title>
8+
</head>
9+
<body>
10+
<div id="app">
11+
<div class="header">
12+
<h1>Debug Libraries Benchmark</h1>
13+
<p class="description">Comparing performance between <code>@wbe/debug</code> and <code>debug</code> libraries</p>
14+
</div>
15+
16+
<div class="console-output">
17+
<h2>Console Output</h2>
18+
<p>Open the browser console (F12) to see detailed benchmark logs</p>
19+
</div>
20+
21+
<!-- Benchmark results will be injected here by the script -->
22+
</div>
23+
<script type="module" src="/src/main.tsx"></script>
24+
</body>
25+
</html>

bench/browser-bench/package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "browser-bench",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc && vite build",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"@wbe/debug": "workspace:*",
13+
"debug": "4.4.0",
14+
"preact": "^10.26.5"
15+
},
16+
"devDependencies": {
17+
"sass": "^1.86.3",
18+
"typescript": "~5.7.2",
19+
"vite": "^6.2.0"
20+
}
21+
}
Lines changed: 1 addition & 0 deletions
Loading

bench/browser-bench/src/App.tsx

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import { useState, useEffect } from "preact/hooks"
2+
import debugOriginal from "debug"
3+
import debugWbe from "@wbe/debug"
4+
5+
// Types for our benchmark results
6+
interface BenchmarkResults {
7+
debugOriginal: number
8+
debugWbe: number
9+
iterations: number
10+
testMessages: any[]
11+
completed: boolean
12+
}
13+
14+
// Preact Components
15+
export const BenchmarkApp = () => {
16+
const [results, setResults] = useState<BenchmarkResults>({
17+
debugOriginal: 0,
18+
debugWbe: 0,
19+
iterations: 10000,
20+
testMessages: [],
21+
completed: false,
22+
})
23+
const [isRunning, setIsRunning] = useState(false)
24+
25+
useEffect(() => {
26+
runBenchmark()
27+
}, [])
28+
29+
const runBenchmark = async () => {
30+
setIsRunning(true)
31+
32+
const logBench = debugWbe("bench:main")
33+
logBench("Starting browser benchmark...")
34+
35+
// Setup for benchmarking
36+
const iterations = 10000
37+
const benchResults = {
38+
debugOriginal: 0,
39+
debugWbe: 0,
40+
}
41+
42+
// Create loggers for each library
43+
const logOriginal = debugOriginal("bench:original")
44+
const logWbe = debugWbe("bench:wbe")
45+
46+
// Warmup phase
47+
logBench("Warming up...")
48+
for (let i = 0; i < 100; i++) {
49+
logOriginal("warmup")
50+
logWbe("warmup")
51+
}
52+
53+
// Setup test messages with different complexity
54+
const testMessages = [
55+
"Simple string message",
56+
["Array", "of", "strings"],
57+
{ complex: "object", with: { nested: "properties" } },
58+
["Mixed", 123, { type: "content" }],
59+
]
60+
61+
// Update state with test messages
62+
setResults((prev) => ({ ...prev, testMessages }))
63+
64+
// Benchmark original debug
65+
logBench("Benchmarking original debug library...")
66+
const originalStart = performance.now()
67+
68+
for (let i = 0; i < iterations; i++) {
69+
const msgIndex = i % testMessages.length
70+
// Use console.time/timeEnd for more granular measurement
71+
if (i % 1000 === 0) console.time("original-" + i)
72+
logOriginal(testMessages[msgIndex])
73+
if (i % 1000 === 0) console.timeEnd("original-" + i)
74+
}
75+
76+
benchResults.debugOriginal = performance.now() - originalStart
77+
78+
// Benchmark @wbe/debug
79+
logBench("Benchmarking @wbe/debug library...")
80+
const wbeStart = performance.now()
81+
82+
for (let i = 0; i < iterations; i++) {
83+
const msgIndex = i % testMessages.length
84+
if (i % 1000 === 0) console.time("wbe-" + i)
85+
logWbe(testMessages[msgIndex])
86+
if (i % 1000 === 0) console.timeEnd("wbe-" + i)
87+
}
88+
89+
benchResults.debugWbe = performance.now() - wbeStart
90+
91+
// Display results
92+
logBench("Browser benchmark completed.")
93+
94+
console.log(
95+
"%c---- BENCHMARK RESULTS ----",
96+
"font-weight: bold; font-size: 16px;"
97+
)
98+
console.log(`Total iterations per library: ${iterations}`)
99+
console.log(
100+
`Original debug: ${benchResults.debugOriginal.toFixed(2)}ms (${(
101+
benchResults.debugOriginal / iterations
102+
).toFixed(3)}ms per call)`
103+
)
104+
console.log(
105+
`@wbe/debug: ${benchResults.debugWbe.toFixed(2)}ms (${(
106+
benchResults.debugWbe / iterations
107+
).toFixed(3)}ms per call)`
108+
)
109+
console.log(
110+
`Difference: ${(
111+
benchResults.debugWbe - benchResults.debugOriginal
112+
).toFixed(2)}ms`
113+
)
114+
115+
if (benchResults.debugWbe < benchResults.debugOriginal) {
116+
console.log(
117+
`%c@wbe/debug is ${(
118+
(benchResults.debugOriginal / benchResults.debugWbe - 1) *
119+
100
120+
).toFixed(2)}% faster`,
121+
"color: green; font-weight: bold"
122+
)
123+
} else {
124+
console.log(
125+
`%cOriginal debug is ${(
126+
(benchResults.debugWbe / benchResults.debugOriginal - 1) *
127+
100
128+
).toFixed(2)}% faster`,
129+
"color: red; font-weight: bold"
130+
)
131+
}
132+
133+
// Update state with results
134+
setResults({
135+
debugOriginal: benchResults.debugOriginal,
136+
debugWbe: benchResults.debugWbe,
137+
iterations,
138+
testMessages,
139+
completed: true,
140+
})
141+
142+
setIsRunning(false)
143+
}
144+
145+
return (
146+
<div>
147+
<div className="actions">
148+
<button onClick={runBenchmark} disabled={isRunning} className="run-btn">
149+
{isRunning ? "Running..." : "Run Benchmark Again"}
150+
</button>
151+
</div>
152+
153+
{isRunning && <div className="loading">Running benchmark...</div>}
154+
155+
{results.completed && <BenchmarkResults results={results} />}
156+
</div>
157+
)
158+
}
159+
160+
const BenchmarkResults = ({ results }: { results: BenchmarkResults }) => {
161+
const { debugOriginal, debugWbe, iterations, testMessages } = results
162+
163+
const originalPerCall = debugOriginal / iterations
164+
const wbePerCall = debugWbe / iterations
165+
const difference = debugWbe - debugOriginal
166+
167+
// Calculate percentage difference
168+
const isWbeFaster = debugWbe < debugOriginal
169+
const percentDiff = isWbeFaster
170+
? ((debugOriginal / debugWbe - 1) * 100).toFixed(2)
171+
: ((debugWbe / debugOriginal - 1) * 100).toFixed(2)
172+
173+
// Calculate bar widths
174+
const maxTime = Math.max(debugOriginal, debugWbe)
175+
const originalBarWidth = `${Math.min(100, (debugOriginal / maxTime) * 100)}%`
176+
const wbeBarWidth = `${Math.min(100, (debugWbe / maxTime) * 100)}%`
177+
178+
return (
179+
<div className="results">
180+
<h2>Benchmark Results</h2>
181+
182+
<div className="summary">
183+
<p>
184+
Total iterations per library: <strong>{iterations}</strong>
185+
</p>
186+
<p className="winner" style={{ color: isWbeFaster ? "green" : "red" }}>
187+
<strong>
188+
{isWbeFaster
189+
? `@wbe/debug is ${percentDiff}% faster`
190+
: `Original debug is ${percentDiff}% faster`}
191+
</strong>
192+
</p>
193+
</div>
194+
195+
<div className="result-bars">
196+
<div className="bar-container">
197+
<div className="bar-label">
198+
Original debug: {debugOriginal.toFixed(2)}ms (
199+
{originalPerCall.toFixed(3)}ms per call)
200+
</div>
201+
<div className="bar original-bar" style={{ width: originalBarWidth }}>
202+
{originalPerCall.toFixed(3)}ms
203+
</div>
204+
</div>
205+
206+
<div className="bar-container">
207+
<div className="bar-label">
208+
@wbe/debug: {debugWbe.toFixed(2)}ms ({wbePerCall.toFixed(3)}ms per
209+
call)
210+
</div>
211+
<div className="bar wbe-bar" style={{ width: wbeBarWidth }}>
212+
{wbePerCall.toFixed(3)}ms
213+
</div>
214+
</div>
215+
</div>
216+
217+
<div className="difference">
218+
<p>Difference: {difference.toFixed(2)}ms</p>
219+
</div>
220+
221+
<div className="test-details">
222+
<h3>Test Details</h3>
223+
<ul>
224+
<li>Iterations: {iterations}</li>
225+
<li>Test performed on: {new Date().toLocaleString()}</li>
226+
<li>Browser: {navigator.userAgent}</li>
227+
</ul>
228+
229+
<h3>Test Messages</h3>
230+
<pre>{JSON.stringify(testMessages, null, 2)}</pre>
231+
</div>
232+
</div>
233+
)
234+
}

bench/browser-bench/src/main.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { render } from "preact"
2+
import { BenchmarkApp } from "./App"
3+
import "./styles/main.scss"
4+
5+
// Enable logs for both libraries
6+
localStorage.setItem("debug", "*")
7+
8+
// Initialize the app
9+
const init = () => {
10+
render(<BenchmarkApp />, document.getElementById("app")!)
11+
}
12+
13+
init()

0 commit comments

Comments
 (0)