mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
111 lines
3.4 KiB
JavaScript
111 lines
3.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { execFileSync } from 'node:child_process'
|
|
import { readFileSync } from 'node:fs'
|
|
import { stripTypeScriptTypes } from 'node:module'
|
|
import { performance } from 'node:perf_hooks'
|
|
|
|
// Run from the worktree root: node config/scripts/benchmark-browser-tunnel-framing.mjs [base-ref]
|
|
const path = 'src/shared/browser-network-tunnel-stream-framing.ts'
|
|
const baselineRef = process.argv[2] ?? 'HEAD'
|
|
const beforeSource = execFileSync('git', ['show', `${baselineRef}:${path}`], {
|
|
encoding: 'utf8'
|
|
})
|
|
const afterSource = readFileSync(path, 'utf8')
|
|
const load = (source) =>
|
|
import(
|
|
`data:text/javascript;base64,${Buffer.from(
|
|
stripTypeScriptTypes(source, { mode: 'transform' })
|
|
).toString('base64')}`
|
|
)
|
|
const before = await load(beforeSource)
|
|
const after = await load(afterSource)
|
|
|
|
function measure(module, chunks, payload, repetitions) {
|
|
let frameCount = 0
|
|
let lastFrame
|
|
const onFrame = (frame) => {
|
|
frameCount++
|
|
lastFrame = frame
|
|
}
|
|
const onError = (error) => {
|
|
throw error
|
|
}
|
|
const run = () => {
|
|
const decoder = new module.BrowserNetworkTunnelStreamFrameDecoder(onFrame, onError)
|
|
for (const chunk of chunks) {
|
|
decoder.feed(chunk)
|
|
}
|
|
}
|
|
run()
|
|
assert.deepEqual(lastFrame, payload)
|
|
const samples = []
|
|
for (let sample = 0; sample < 5; sample++) {
|
|
const start = performance.now()
|
|
for (let iteration = 0; iteration < repetitions; iteration++) {
|
|
run()
|
|
}
|
|
samples.push((performance.now() - start) / repetitions)
|
|
}
|
|
assert.equal(frameCount, 1 + 5 * repetitions)
|
|
return samples.sort((a, b) => a - b)[2]
|
|
}
|
|
|
|
function countCopies(module, chunks) {
|
|
const originalSet = Uint8Array.prototype.set
|
|
const originalSlice = Uint8Array.prototype.slice
|
|
let copied = 0
|
|
Uint8Array.prototype.set = function (source, offset) {
|
|
copied += source.length
|
|
return originalSet.call(this, source, offset)
|
|
}
|
|
Uint8Array.prototype.slice = function (...args) {
|
|
const result = originalSlice.apply(this, args)
|
|
copied += result.length
|
|
return result
|
|
}
|
|
try {
|
|
const decoder = new module.BrowserNetworkTunnelStreamFrameDecoder(
|
|
() => {},
|
|
(error) => {
|
|
throw error
|
|
}
|
|
)
|
|
for (const chunk of chunks) {
|
|
decoder.feed(chunk)
|
|
}
|
|
} finally {
|
|
Uint8Array.prototype.set = originalSet
|
|
Uint8Array.prototype.slice = originalSlice
|
|
}
|
|
return copied
|
|
}
|
|
|
|
const rows = []
|
|
for (const [payloadBytes, chunkBytes, repetitions] of [
|
|
[1, 5, 10000],
|
|
[64 * 1024, 65540, 1000],
|
|
[64 * 1024, 4096, 100],
|
|
[64 * 1024, 256, 25],
|
|
[64 * 1024, 16, 5],
|
|
[64 * 1024, 1, 1]
|
|
]) {
|
|
const payload = Uint8Array.from({ length: payloadBytes }, (_, index) => index % 251)
|
|
const encoded = before.encodeBrowserNetworkTunnelStreamFrame(payload)
|
|
const chunks = []
|
|
for (let offset = 0; offset < encoded.length; offset += chunkBytes) {
|
|
chunks.push(encoded.subarray(offset, offset + chunkBytes))
|
|
}
|
|
const beforeMs = measure(before, chunks, payload, repetitions)
|
|
const afterMs = measure(after, chunks, payload, repetitions)
|
|
rows.push({
|
|
payloadBytes,
|
|
chunkBytes,
|
|
beforeMs: +beforeMs.toFixed(6),
|
|
afterMs: +afterMs.toFixed(6),
|
|
speedup: +(beforeMs / afterMs).toFixed(2),
|
|
beforeCopiedBytes: countCopies(before, chunks),
|
|
afterCopiedBytes: countCopies(after, chunks)
|
|
})
|
|
}
|
|
console.log(JSON.stringify({ node: process.version, baselineRef, rows }, null, 2))
|