@timeseries/bucket-sampler
v0.1.2
Published
Time-series bucket sampling: slices, iterators, and wasm-bindgen basics
Maintainers
Readme
@timeseries/ts-bucket-sampler
WebAssembly-powered time-series downsampling for Node.js and browsers.
Installation
npm install @timeseries/ts-bucket-samplerUsage
import init, {
lttbIndices,
lttbValues,
minmaxIndices,
minmaxValues,
firstlastIndices,
firstlastValues,
} from "@timeseries/ts-bucket-sampler";
await init();
const timestamps = new Float64Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
const values = new Float64Array([0, 10, 5, 20, 3, 15, 8, 25, 1, 12]);
const numSamples = 4;
// Returns indices into the original arrays (Uint32Array)
const indices = lttbIndices(timestamps, values, numSamples);
// Returns flat [t0, v0, t1, v1, ...] interleaved pairs (Float64Array)
const pairs = lttbValues(timestamps, values, numSamples);Functions
| Function | Description | Returns |
|----------|------------|---------|
| lttbIndices | Largest-Triangle-Three-Buckets — preserves visual shape | Uint32Array |
| lttbValues | LTTB — interleaved [t, v, ...] pairs | Float64Array |
| minmaxIndices | MinMax — keeps both min and max per bucket | Uint32Array |
| minmaxValues | MinMax — interleaved pairs | Float64Array |
| firstlastIndices | First + last per bucket (fastest) | Uint32Array |
| firstlastValues | FirstLast — interleaved pairs | Float64Array |
Performance (Node.js)
Benchmarked on 1M points → 10k samples (1%):
| Function | Time | Throughput |
|----------|------|----------|
| lttbIndices | ~5.9s | ~170M pts/sec |
| firstlastIndices | ~1.8s | ~560M pts/sec |
| minmaxIndices | ~6.6s | ~150M pts/sec |
Benchmarked on 100K → 1k (1%):
| Function | Time |
|----------|------|
| lttbIndices | ~529ms |
| firstlastIndices | ~113ms |
| minmaxIndices | ~711ms |
import { performance } from "node:perf_hooks";
import init, { lttbValues } from "@timeseries/ts-bucket-sampler";
await init();
const N = 10_000_000;
const timestamps = new Float64Array(N).map((_, i) => i);
const values = new Float64Array(N).map((_, i) => Math.sin(i / 100));
// Warm up
for (let i = 0; i < 3; i++) lttbValues(timestamps, values, 5000);
// Benchmark
const RUNS = 20;
const start = performance.now();
for (let i = 0; i < RUNS; i++) {
lttbValues(timestamps, values, 5000);
}
const elapsed = (performance.now() - start) / RUNS;
console.log(`${elapsed.toFixed(1)} ms/call`);
console.log(`${(N / (elapsed / 1000) / 1e6).toFixed(0)}M pts/sec`);Memory
Float64Arrayinput is zero-copy — shared WASM memory view- Returned arrays are copied out of WASM linear memory
License
MIT OR Apache-2.0
