-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import {writeFile, rm} from 'node:fs/promises'; | ||
|
||
// Create and delete a big fixture file | ||
export const createFixture = async () => { | ||
await writeFile(FIXTURE_FILE, '.'.repeat(FIXTURE_BYTE_SIZE)); | ||
}; | ||
|
||
export const deleteFixture = async () => { | ||
await rm(FIXTURE_FILE); | ||
}; | ||
|
||
export const FIXTURE_FILE = 'benchmark_fixture'; | ||
|
||
const FIXTURE_BYTE_SIZE = 1e8; | ||
export const FIXTURE_HUMAN_SIZE = `${FIXTURE_BYTE_SIZE / 1e6} MB`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import {text, buffer, arrayBuffer} from 'node:stream/consumers'; | ||
import getStream, {getStreamAsBuffer, getStreamAsArrayBuffer, getStreamAsArray} from '../index.js'; | ||
import {createFixture, deleteFixture, FIXTURE_HUMAN_SIZE} from './fixture.js'; | ||
import {createNodeStreamBinary, createNodeStreamText, createWebStreamBinary, createWebStreamText} from './stream.js'; | ||
import {measureTask} from './measure.js'; | ||
|
||
const runBenchmarks = async () => { | ||
await createFixture(); | ||
|
||
try { | ||
await benchmarkNodeStreams(createNodeStreamBinary, `Node.js stream (${FIXTURE_HUMAN_SIZE}, binary)`); | ||
await benchmarkNodeStreams(createNodeStreamText, `Node.js stream (${FIXTURE_HUMAN_SIZE}, text)`); | ||
await benchmarkStreams(createWebStreamBinary, `Web ReadableStream (${FIXTURE_HUMAN_SIZE}, binary)`); | ||
await benchmarkStreams(createWebStreamText, `Web ReadableStream (${FIXTURE_HUMAN_SIZE}, text)`); | ||
} finally { | ||
await deleteFixture(); | ||
} | ||
}; | ||
|
||
const benchmarkNodeStreams = async (createStream, header) => { | ||
await benchmarkStreams(createStream, header); | ||
await logResult('stream.toArray', createStream, stream => stream.toArray()); | ||
}; | ||
|
||
const benchmarkStreams = async (createStream, header) => { | ||
logHeader(header); | ||
await logResult('getStream', createStream, getStream); | ||
await logResult('text', createStream, text); | ||
await logResult('getStreamAsBuffer', createStream, getStreamAsBuffer); | ||
await logResult('buffer', createStream, buffer); | ||
await logResult('getStreamAsArrayBuffer', createStream, getStreamAsArrayBuffer); | ||
await logResult('arrayBuffer', createStream, arrayBuffer); | ||
await logResult('getStreamAsArray', createStream, getStreamAsArray); | ||
}; | ||
|
||
const logHeader = header => { | ||
console.log(`\n### ${header}\n`); | ||
}; | ||
|
||
const logResult = async (name, createStream, task) => { | ||
console.log(`- \`${name}()\`: ${await measureTask(createStream, task)}ms`); | ||
}; | ||
|
||
await runBenchmarks(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import now from 'precise-now'; | ||
|
||
// Return how many ms running `task()` takes | ||
export const measureTask = async ({start, stop}, task) => { | ||
const taskInputs = await Promise.all(Array.from({length: MAX_LOOPS + 1}, start)); | ||
|
||
// Pre-warm | ||
await task(taskInputs[0].stream); | ||
|
||
const startTimestamp = now(); | ||
for (let index = 1; index <= MAX_LOOPS; index += 1) { | ||
// eslint-disable-next-line no-await-in-loop | ||
await task(taskInputs[index].stream); | ||
} | ||
|
||
const duration = Math.round((now() - startTimestamp) / (MAX_LOOPS * NANOSECS_TO_MILLESECS)); | ||
|
||
await Promise.all(taskInputs.map(taskInput => stop(taskInput))); | ||
|
||
return duration; | ||
}; | ||
|
||
const MAX_LOOPS = 10; | ||
const NANOSECS_TO_MILLESECS = 1e6; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import {open} from 'node:fs/promises'; | ||
import {createReadStream} from 'node:fs'; | ||
import {FIXTURE_FILE} from './fixture.js'; | ||
|
||
const createNodeStream = encoding => ({ | ||
start: () => ({stream: createReadStream(FIXTURE_FILE, encoding)}), | ||
stop() {}, | ||
}); | ||
|
||
export const createNodeStreamBinary = createNodeStream(undefined); | ||
export const createNodeStreamText = createNodeStream('utf8'); | ||
|
||
const createWebStream = type => ({ | ||
async start() { | ||
const fileHandle = await open(FIXTURE_FILE); | ||
const stream = fileHandle.readableWebStream({type}); | ||
return {fileHandle, stream}; | ||
}, | ||
async stop({fileHandle}) { | ||
await fileHandle.close(); | ||
}, | ||
}); | ||
|
||
export const createWebStreamBinary = createWebStream('bytes'); | ||
// `Text` is somewhat of a misnomer here: | ||
// - `fs.readableWebStream({ type: 'bytes' })` creates a `ReadableStream` with a "bytes controller" and `Uint8Array` chunks | ||
// - `fs.readableWebStream({ type: undefined })` creates a `ReadableStream` with a "default controller" and `ArrayBuffer` chunks. | ||
// Node.js currently does not allow creating a file-based `ReadableStream` with string chunks. | ||
export const createWebStreamText = createWebStream(undefined); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters