Added temporary benchmarks
This commit is contained in:
parent
450745011a
commit
0f7ccb2a0a
@ -1,6 +1,6 @@
|
||||
import { tryCatch, type Result } from '@maxmorozoff/try-catch-tuple';
|
||||
import { type Result, tryCatch } from '@maxmorozoff/try-catch-tuple'
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const encoder = new TextEncoder()
|
||||
|
||||
export const ANSI = {
|
||||
// Text Styles
|
||||
@ -51,7 +51,7 @@ export const ANSI = {
|
||||
CLEAR_TO_END: '\x1B[0J', // From cursor to end of screen
|
||||
CLEAR_TO_START: '\x1B[1J', // From cursor to beginning of screen
|
||||
CLEAR_BELOW: '\x1B[J',
|
||||
};
|
||||
}
|
||||
|
||||
export const ANSI_BUFFERS = {
|
||||
// Static code buffers
|
||||
@ -95,7 +95,7 @@ export const ANSI_BUFFERS = {
|
||||
CLEAR_TO_END: encoder.encode(ANSI.CLEAR_TO_END),
|
||||
CLEAR_TO_START: encoder.encode(ANSI.CLEAR_TO_START),
|
||||
CLEAR_BELOW: encoder.encode(ANSI.CLEAR_BELOW),
|
||||
};
|
||||
}
|
||||
|
||||
export const ANSI_DYNAMIC = {
|
||||
// Cursor Control
|
||||
@ -104,49 +104,141 @@ export const ANSI_DYNAMIC = {
|
||||
CURSOR_DOWN: (x = 1) => encoder.encode(ANSI.CURSOR_DOWN(x)),
|
||||
CURSOR_FORWARD: (x = 1) => encoder.encode(ANSI.CURSOR_FORWARD(x)),
|
||||
CURSOR_BACK: (x = 1) => encoder.encode(ANSI.CURSOR_BACK(x)),
|
||||
};
|
||||
}
|
||||
|
||||
type AnsiBufferKey = keyof typeof ANSI_BUFFERS;
|
||||
type AnsiBufferKey = keyof typeof ANSI_BUFFERS
|
||||
|
||||
export async function writeAnsi(
|
||||
codes: (AnsiBufferKey | Uint8Array)[],
|
||||
text?: string,
|
||||
autoReset: boolean = true
|
||||
autoReset: boolean = true,
|
||||
): Promise<Result<number, Error>> {
|
||||
const buffers: Uint8Array[] = [];
|
||||
const buffers: Uint8Array[] = []
|
||||
|
||||
// Add requested ANSI codes
|
||||
for (const code of codes) {
|
||||
if (code instanceof Uint8Array) {
|
||||
buffers.push(code);
|
||||
buffers.push(code)
|
||||
} else {
|
||||
buffers.push(ANSI_BUFFERS[code]);
|
||||
buffers.push(ANSI_BUFFERS[code])
|
||||
}
|
||||
}
|
||||
|
||||
// Add optional text
|
||||
if (text) {
|
||||
buffers.push(encoder.encode(text));
|
||||
buffers.push(encoder.encode(text))
|
||||
}
|
||||
|
||||
// Auto-reset if requested
|
||||
if (autoReset && !codes.includes('RESET')) {
|
||||
buffers.push(ANSI_BUFFERS.RESET);
|
||||
buffers.push(ANSI_BUFFERS.RESET)
|
||||
}
|
||||
|
||||
// Combine all buffers into single write
|
||||
const combined = new Uint8Array(
|
||||
buffers.reduce((acc, buf) => acc + buf.length, 0)
|
||||
);
|
||||
buffers.reduce((acc, buf) => acc + buf.length, 0),
|
||||
)
|
||||
|
||||
let offset = 0;
|
||||
let offset = 0
|
||||
for (const buf of buffers) {
|
||||
combined.set(buf, offset);
|
||||
offset += buf.length;
|
||||
combined.set(buf, offset)
|
||||
offset += buf.length
|
||||
}
|
||||
|
||||
return tryCatch(() => Bun.write(Bun.stdout, combined));
|
||||
// return tryCatch(() => Bun.write(Bun.stdout, combined))
|
||||
return tryCatch(() => process.stdout.write(combined))
|
||||
}
|
||||
|
||||
export async function writeAnsi2(
|
||||
codes: (AnsiBufferKey | Uint8Array)[],
|
||||
text?: string,
|
||||
autoReset: boolean = true,
|
||||
): Promise<Result<number, Error>> {
|
||||
const buffers: Uint8Array[] = []
|
||||
|
||||
// Add requested ANSI codes
|
||||
for (const code of codes) {
|
||||
if (code instanceof Uint8Array) {
|
||||
buffers.push(code)
|
||||
} else {
|
||||
buffers.push(ANSI_BUFFERS[code])
|
||||
}
|
||||
}
|
||||
|
||||
// Add optional text
|
||||
if (text) {
|
||||
buffers.push(encoder.encode(text))
|
||||
}
|
||||
|
||||
// Auto-reset if requested
|
||||
if (autoReset && !codes.includes('RESET')) {
|
||||
buffers.push(ANSI_BUFFERS.RESET)
|
||||
}
|
||||
|
||||
// Combine all buffers into single write
|
||||
const combined = new Uint8Array(
|
||||
buffers.reduce((acc, buf) => acc + buf.length, 0),
|
||||
)
|
||||
|
||||
let offset = 0
|
||||
for (const buf of buffers) {
|
||||
combined.set(buf, offset)
|
||||
offset += buf.length
|
||||
}
|
||||
|
||||
return Bun.write(Bun.stdout, combined)
|
||||
// return tryCatch(() => process.stdout.write(combined))
|
||||
}
|
||||
|
||||
// For CommonJS compatibility
|
||||
export default { ANSI, ANSI_BUFFERS, writeAnsi };
|
||||
export default {ANSI, ANSI_BUFFERS, writeAnsi}
|
||||
|
||||
const testNum = 5
|
||||
// const testCase = [['BG_WHITE', 'BLACK'], 'This is some text']
|
||||
const testCase =
|
||||
`${ANSI_BUFFERS.BG_WHITE}${ANSI_BUFFERS.BLACK}This is some text${ANSI_BUFFERS.RESET}`
|
||||
const testCase2 = `${ANSI.BG_WHITE}${ANSI.BLACK}This is some text`
|
||||
|
||||
const bench = async (x, y, n) => {
|
||||
const a = Bun.nanoseconds()
|
||||
|
||||
let i = 0
|
||||
while (i < n) {
|
||||
await x(y)
|
||||
i++
|
||||
}
|
||||
const b = Bun.nanoseconds()
|
||||
return writeAnsi2(['YELLOW'], `${Math.round((b - a) / 1000000)}ms`)
|
||||
}
|
||||
|
||||
const out = async (a, b, c) => {
|
||||
const one = await a
|
||||
const two = await b
|
||||
const three = await c
|
||||
|
||||
const log = x => async y => console.log(x, await y)
|
||||
const diff = x => y => {
|
||||
if (y < x) return Math.round(((y - x) / y) * 100)
|
||||
return Math.round(((y - x) / x) * 100)
|
||||
}
|
||||
|
||||
writeAnsi(['RESET', 'CLEAR_SCREEN', ANSI_DYNAMIC.CURSOR_TO(0, 0)])
|
||||
|
||||
console.log('')
|
||||
console.log('---------------')
|
||||
console.log('Output in milliseconds')
|
||||
console.log('---------------')
|
||||
log('ANSI: ')(!one ? '' : one)
|
||||
log('ANSI_BUFFERS: ')(!two ? '' : two)
|
||||
log('THREE: ')(!three ? '' : three)
|
||||
log(`${diff(one)(two)}%`)('faster')
|
||||
}
|
||||
out(
|
||||
bench(x => Bun.write(Bun.stdout, x), testCase, testNum),
|
||||
bench(x => Bun.write(Bun.stdout, x), testCase2, testNum),
|
||||
bench(
|
||||
x => writeAnsi2(...x),
|
||||
[['BG_WHITE', 'BLACK'], 'This is some text'],
|
||||
testNum,
|
||||
),
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user