Skip to content

Instantly share code, notes, and snippets.

@Jonarod
Forked from bwasti/readlines.js
Created March 21, 2023 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jonarod/7fd1de2c055849131d48eac9cd38f45b to your computer and use it in GitHub Desktop.
Save Jonarod/7fd1de2c055849131d48eac9cd38f45b to your computer and use it in GitHub Desktop.
Fast line reading in bun
async function readlines(stream, callback, buffer_len = 16) {
const reader = stream.getReader()
const td = new TextDecoder('ascii')
let overflow = null
let buffer = []
function flush_buffer() {
for (let b of buffer) {
callback(td.decode(b))
}
buffer = []
}
function add_to_buffer(b) {
buffer.push(b)
if (buffer.length >= buffer_len) {
flush_buffer()
}
}
function process(value) {
let i = -1
let last_nl = 0
while ((i = value.indexOf('\n'.charCodeAt(0), i + 1)) >= 0) {
const next_line = value.slice(last_nl, i)
if (overflow && overflow.length) {
const merge = new Uint8Array(overflow.length + next_line.length)
merge.set(overflow)
merge.set(next_line, overflow.length)
add_to_buffer(merge)
overflow = null
} else {
add_to_buffer(next_line)
}
if (i >= 0) {
last_nl = i + 1
}
}
if (last_nl != value.length) {
overflow = value.slice(last_nl, value.length)
}
}
while (true) {
const b = await reader.read()
if (!b.value) {
break
}
process(b.value)
}
if (overflow) {
add_to_buffer(overflow)
}
flush_buffer()
}
const t0 = performance.now()
const stream = Bun.file("input.txt").stream()
let out = []
await readlines(stream, (line) => {
const [a, b, c] = line.split(',').map(Number)
const n = 4 * a + b * b + (c / 3)
if (out.length && out[out.length - 1] > n) {
out.push(n - out[out.length - 1])
}
out.push(n)
})
const d = (performance.now() - t0) / 1e3
console.log("computed", out.length, "in", d, "seconds")
console.log(out.length / d, "lines/sec")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment