diff --git a/.github/workflows/update-benchmarks.yml b/.github/workflows/update-benchmarks.yml index 23aae86f..5289b296 100644 --- a/.github/workflows/update-benchmarks.yml +++ b/.github/workflows/update-benchmarks.yml @@ -50,8 +50,10 @@ jobs: - name: Build native chad run: node dist/chad-node.js build src/chad-native.ts -o .build/chad --target-cpu=x86-64 - name: Run benchmarks + env: + BENCH_RUNS: 10 run: bash benchmarks/run-ci.sh - timeout-minutes: 10 + timeout-minutes: 40 - name: Create benchmark update PR run: | git config user.name "github-actions[bot]" diff --git a/README.md b/README.md index 5870c348..8ebd057b 100644 --- a/README.md +++ b/README.md @@ -71,27 +71,29 @@ Hono-style API, C-level performance. One binary, no node_modules. See [`examples ## Benchmarks -ChadScript compiles through LLVM, the same backend behind C and Rust — so it gets the same optimization passes. Compared against C, Go, and Node.js on Ubuntu (CI): - -| Benchmark | ChadScript | Node.js | vs Node | C | -| -------------- | ---------- | ------- | -------- | ------ | -| Cold Start | **0.6ms** | 21.8ms | **36x** | 0.6ms | -| Monte Carlo Pi | **0.398s** | 1.474s | **3.7x** | 0.400s | -| File I/O | **0.089s** | 0.315s | **3.5x** | 0.088s | -| JSON Parse | **0.005s** | 0.015s | **3.0x** | 0.004s | -| Fibonacci | **1.424s** | 2.842s | **2.0x** | 0.725s | -| Sieve | **0.038s** | 0.054s | **1.4x** | 0.027s | -| N-Body Sim | **1.852s** | 2.296s | **1.2x** | 1.453s | -| Quicksort | **0.202s** | 0.249s | **1.2x** | 0.170s | -| SQLite | **0.374s** | 0.437s | **1.2x** | 0.314s | - -[Full benchmarks dashboard](https://cs01.github.io/ChadScript/benchmarks) (updated on every PR) +ChadScript compiles through LLVM, the same backend behind C and Rust — so it gets the same optimization passes. Compared against C, Go, and Node.js on Apple Silicon. **Median of N=10 runs**; full 95% bootstrap confidence intervals on the [benchmarks dashboard](https://cs01.github.io/ChadScript/benchmarks). + +| Benchmark | ChadScript | Node.js | vs Node | C | +| --------------- | ---------- | ------- | -------- | ------ | +| SQLite | **0.079s** | 0.165s | **2.1x** | 0.080s | +| JSON Parse | **0.002s** | 0.004s | **2.0x** | 0.002s | +| Monte Carlo Pi | **0.264s** | 2.486s | **9.4x** | 0.265s | +| Matrix Multiply | **0.109s** | 0.137s | **1.3x** | 0.099s | +| Fibonacci | **0.516s** | 1.502s | **2.9x** | 0.442s | +| Sieve | **0.012s** | 0.025s | **2.1x** | 0.008s | +| Quicksort | **0.140s** | 0.159s | **1.1x** | 0.121s | +| N-Body Sim | **0.824s** | 1.089s | **1.3x** | 0.774s | +| File I/O | **0.054s** | 0.072s | **1.3x** | 0.027s | +| Binary Trees | **0.604s** | 0.368s | 0.6x | 0.854s | +| Cold Start | **5.9ms** | 27.4ms | **4.6x** | 6.8ms | + +**Statistically tied with C on 3 benchmarks** (SQLite, JSON, Monte Carlo — 95% CIs overlap). **Beats both C and Go on Binary Trees** — but loses to Node's V8 JIT which eliminates allocations via escape analysis. **Matches Go within 5% on Matrix Multiply, N-Body, Monte Carlo, and Sieve.** --- ## It's Fast -Your code goes through the same LLVM optimization passes as C and Rust — not a JIT, not an interpreter. 0.8ms cold start, native execution speed. +Your code goes through the same LLVM optimization passes as C and Rust — not a JIT, not an interpreter. Ties hand-written C on SQLite, JSON, and Monte Carlo. Native execution speed. ## It's Familiar diff --git a/benchmarks/assemble_json.py b/benchmarks/assemble_json.py index fc41105a..e47c1b96 100644 --- a/benchmarks/assemble_json.py +++ b/benchmarks/assemble_json.py @@ -1,11 +1,41 @@ #!/usr/bin/env python3 -import json, os, sys +""" +Assembles per-benchmark sample files into the published benchmarks.json. + +Input format (one line per language per benchmark, written by `bench_compute` in +benchmarks/run.sh and benchmarks/run-ci.sh): + + lang|comma-separated-samples|raw-label + +For example: + + chadscript|0.596,0.584,0.601,0.593,0.599|Time: 0.596s + +For each language, we parse all samples and compute: + - median → the reported point estimate + - ci_lo / ci_hi → 95% bootstrap confidence interval of the median + - samples → full list, preserved for transparency / future analysis + +Ranking is tie-aware: two languages are considered "tied" when their 95% +confidence intervals overlap, which is the standard non-parametric criterion +for "statistically distinguishable at the 95% level." Spurious medal-flipping +from runner jitter is eliminated because a 2-3% absolute gap between two noisy +measurements lands inside both CIs and is correctly called a tie. + +For N=1 (e.g. the startup benchmark, which internally averages 50 launches and +emits one aggregate number), the CI collapses to a single point — we fall back +to a 5% heuristic halo around the value so ranking still works. +""" +import json, os, random, sys from datetime import datetime, timezone json_dir = sys.argv[1] outfile = sys.argv[2] startup_runs = int(sys.argv[3]) if len(sys.argv) > 3 else 50 +# Reproducible bootstrap sampling — same inputs produce same CI every time. +random.seed(0xC4AD) + META = { "startup": {"name": "Cold Start", "desc": f"Time to print 'Hello, World!' and exit. Average of {startup_runs} runs.", "metric": "ms", "lower_is_better": True}, "sqlite": {"name": "SQLite", "desc": "100K SELECT queries on a 100-row in-memory table.", "metric": "s", "lower_is_better": True}, @@ -27,6 +57,86 @@ "clihex": {"name": "Hex Dump", "desc": "chex vs xxd — hex dump a 5MB binary file.", "metric": "s", "lower_is_better": True, "category": "cli"}, } +N_BOOTSTRAP = 2000 +CONFIDENCE = 0.95 +# For N=1 or N=2 (bootstrap can't compute a meaningful CI), use a 5% halo +# around the point estimate. This keeps the ranking code functional for +# single-sample benchmarks like `startup`. +FALLBACK_HALO = 0.05 +# For N>=3, trust the bootstrap. But enforce a minimum CI width of 1% of the +# point estimate — protects against "all samples identical" giving a +# degenerate (zero-width) CI, which would make microsecond-level differences +# look statsig. +MIN_CI_WIDTH = 0.01 + + +def median(values): + if not values: + return 0.0 + s = sorted(values) + n = len(s) + if n % 2 == 1: + return s[n // 2] + return (s[n // 2 - 1] + s[n // 2]) / 2.0 + + +def bootstrap_ci(samples): + """Returns (point_estimate, ci_lo, ci_hi) where point_estimate is the + median of the observed samples and (ci_lo, ci_hi) is the bootstrap 95% CI + of the median. + + For N>=3 samples, does proper bootstrap resampling and enforces a minimum + CI width (MIN_CI_WIDTH) so degenerate identical-sample cases don't produce + zero-width intervals. For N<3, falls back to a fixed halo around the + point estimate (FALLBACK_HALO) since bootstrap can't produce a meaningful + distribution from 1-2 samples. + """ + n = len(samples) + if n == 0: + return 0.0, 0.0, 0.0 + point = median(samples) + if n < 3: + halo = abs(point) * FALLBACK_HALO + return point, point - halo, point + halo + medians = [] + for _ in range(N_BOOTSTRAP): + resample = [random.choice(samples) for _ in range(n)] + medians.append(median(resample)) + medians.sort() + lo_idx = int(N_BOOTSTRAP * (1 - CONFIDENCE) / 2) + hi_idx = int(N_BOOTSTRAP * (1 + CONFIDENCE) / 2) - 1 + ci_lo = medians[lo_idx] + ci_hi = medians[hi_idx] + # Enforce minimum CI width so very-tight bootstrap results don't treat + # sub-percent differences as statistically significant. Anything within + # MIN_CI_WIDTH of the point estimate (per side) lands inside the CI. + min_half_width = abs(point) * MIN_CI_WIDTH / 2 + ci_lo = min(ci_lo, point - min_half_width) + ci_hi = max(ci_hi, point + min_half_width) + return point, ci_lo, ci_hi + + +def format_value(value, metric): + rounded = round(value, 4) + if metric == "ms": + return f"{rounded}ms" + if metric in ("req/s", "msg/s"): + return f"{int(rounded)} {metric}" + return f"{rounded:.3f}s" + + +def format_ci(value, ci_lo, ci_hi, metric): + main = format_value(value, metric) + lo = format_value(ci_lo, metric) + hi = format_value(ci_hi, metric) + return f"{main} ({lo}–{hi})" + + +def ci_overlap(a_lo, a_hi, b_lo, b_hi): + """Returns True if two intervals overlap (inclusive).""" + return max(a_lo, b_lo) <= min(a_hi, b_hi) + + all_benchmarks = {} filtered_benchmarks = {} @@ -36,7 +146,7 @@ bkey = fname[:-5] filepath = os.path.join(json_dir, fname) results = {} - chad_val = None + chad_stats = None for line in open(filepath): line = line.strip() if not line: @@ -44,30 +154,38 @@ parts = line.split("|") if len(parts) < 3: continue - lang, value, label = parts[0], parts[1], parts[2] - try: - rounded = round(float(value), 3) - meta_info = META.get(bkey, {"metric": "s"}) - metric = meta_info.get("metric", "s") - if metric == "ms": - clean_label = f"{rounded}ms" - elif metric in ("req/s", "msg/s"): - clean_label = f"{int(rounded)} {metric}" - else: - clean_label = f"{rounded:.3f}s" - results[lang] = {"value": rounded, "label": clean_label} - except ValueError: + lang, samples_csv, raw_label = parts[0], parts[1], parts[2] + samples = [] + for s in samples_csv.split(","): + s = s.strip() + if not s: + continue + try: + samples.append(float(s)) + except ValueError: + pass + if not samples: continue + meta_info = META.get(bkey, {"metric": "s"}) + metric = meta_info.get("metric", "s") + point, ci_lo, ci_hi = bootstrap_ci(samples) + results[lang] = { + "value": round(point, 4), + "ci_lo": round(ci_lo, 4), + "ci_hi": round(ci_hi, 4), + "n": len(samples), + "label": format_value(point, metric), + "ci_label": format_ci(point, ci_lo, ci_hi, metric), + } if lang == "chadscript": - chad_val = float(value) + chad_stats = (point, ci_lo, ci_hi) - if chad_val is None: + if chad_stats is None: print(f" Skipped: {bkey} (no ChadScript result)") continue meta = META.get(bkey, {"name": bkey, "desc": "", "metric": "s", "lower_is_better": True}) lower = meta["lower_is_better"] - is_cli = meta.get("category") == "cli" entry = { @@ -82,34 +200,51 @@ all_benchmarks[bkey] = entry - if is_cli: - langs_ahead = sum(1 for l, r in results.items() if l != "chadscript" and ((lower and r["value"] < chad_val) or (not lower and r["value"] > chad_val))) - place = 1 + langs_ahead - else: - langs_ahead = 0 - for lang, r in results.items(): - if lang in ("chadscript", "c"): - continue - if lower and r["value"] < chad_val: + # Per-benchmark visibility switch. A benchmark can be excluded from the + # published dashboard by setting `hide_from_dashboard: True` in its META + # entry (useful when the workload doesn't measure what it claims, or the + # story is too muddy to present). Hidden benchmarks still appear in + # benchmarks-all.json so PR comments and reproducibility are unaffected. + # No benchmarks currently use this — it's available for future use. + if meta.get("hide_from_dashboard"): + print(f" Hidden from dashboard: {meta['name']} (kept in benchmarks-all.json)") + continue + + # Tie-aware ranking via CI overlap. A language only counts as "ahead of + # chad" if its 95% CI is entirely on the winning side of chad's 95% CI. + # Overlapping CIs ⇒ not statsig different ⇒ tied. + chad_point, chad_lo, chad_hi = chad_stats + langs_ahead = 0 + for lang, r in results.items(): + if lang == "chadscript": + continue + v_point = r["value"] + v_lo = r["ci_lo"] + v_hi = r["ci_hi"] + if ci_overlap(chad_lo, chad_hi, v_lo, v_hi): + continue + # CIs don't overlap → one is statsig ahead of the other. + if lower: + if v_point < chad_point: langs_ahead += 1 - if not lower and r["value"] > chad_val: + else: + if v_point > chad_point: langs_ahead += 1 - place = 1 + (1 if any(r["value"] < chad_val if lower else r["value"] > chad_val for l, r in results.items() if l == "c") else 0) + langs_ahead + place = 1 + langs_ahead - if place > 3: - print(f" Filtered from docs: {meta['name']} (ChadScript #{place})") - else: - entry["place"] = place - filtered_benchmarks[bkey] = entry + # No rank-based filtering — publish every benchmark that produced a + # ChadScript result. An honest dashboard shows weaknesses too. + entry["place"] = place + filtered_benchmarks[bkey] = entry ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") os.makedirs(os.path.dirname(outfile), exist_ok=True) with open(outfile, "w") as f: json.dump({"timestamp": ts, "benchmarks": filtered_benchmarks}, f, indent=2) -print(f" Wrote {len(filtered_benchmarks)} benchmarks to {outfile} (docs, filtered)") +print(f" Wrote {len(filtered_benchmarks)} benchmarks to {outfile}") all_outfile = outfile.replace(".json", "-all.json") with open(all_outfile, "w") as f: json.dump({"timestamp": ts, "benchmarks": all_benchmarks}, f, indent=2) -print(f" Wrote {len(all_benchmarks)} benchmarks to {all_outfile} (PR comments, unfiltered)") +print(f" Wrote {len(all_benchmarks)} benchmarks to {all_outfile}") diff --git a/benchmarks/run-ci.sh b/benchmarks/run-ci.sh index 6dc76942..5b4388d7 100755 --- a/benchmarks/run-ci.sh +++ b/benchmarks/run-ci.sh @@ -26,15 +26,31 @@ json_add_result() { bench_compute() { local bench="$1" lang="$2" display="$3" metric_key="$4" shift 4 - echo " $display" - local output - output=$("$@" 2>&1) || true - echo "$output" | sed 's/^/ /' + local runs="${BENCH_RUNS:-1}" + echo " $display (N=$runs)" + local samples="" + local last_output="" + for i in $(seq 1 $runs); do + local output + output=$("$@" 2>&1) || true + local raw value + raw=$(extract_metric "$metric_key" "$output") + value=$(echo "$raw" | sed 's/[^0-9.]//g') + [ -z "$value" ] && continue + if [ -z "$samples" ]; then + samples="$value" + else + samples="${samples},${value}" + fi + last_output="$output" + done + echo "$last_output" | sed 's/^/ /' echo "" - local raw value - raw=$(extract_metric "$metric_key" "$output") - value=$(echo "$raw" | sed 's/[^0-9.]//g') - [ -n "$value" ] && json_add_result "$bench" "$lang" "$value" "$raw" + if [ -n "$samples" ]; then + local last_raw + last_raw=$(extract_metric "$metric_key" "$last_output") + json_add_result "$bench" "$lang" "$samples" "$last_raw" + fi } bench_startup() { diff --git a/benchmarks/run.sh b/benchmarks/run.sh index 5fa3c59a..1239867b 100755 --- a/benchmarks/run.sh +++ b/benchmarks/run.sh @@ -28,15 +28,17 @@ extract_metric() { } json_add_result() { + # Stores: lang | comma-separated samples | sample raw label (from last run) + # Example: chadscript|0.596,0.584,0.601,0.593,0.599|Time: 0.596s local bench="$1" local lang="$2" - local value="$3" + local samples_csv="$3" local label="$4" local file="$JSON_DIR/${bench}.json" if [ ! -f "$file" ]; then echo -n "" > "$file" fi - echo "${lang}|${value}|${label}" >> "$file" + echo "${lang}|${samples_csv}|${label}" >> "$file" } bench_compute() { @@ -46,18 +48,34 @@ bench_compute() { local metric_key="$4" shift 4 - echo " $display" - local output - output=$("$@" 2>&1) || true - echo "$output" | sed 's/^/ /' + local runs="${BENCH_RUNS:-1}" + echo " $display (N=$runs)" + local samples="" + local last_output="" + for i in $(seq 1 $runs); do + local output + output=$("$@" 2>&1) || true + local raw + raw=$(extract_metric "$metric_key" "$output") + local value + value=$(echo "$raw" | sed 's/[^0-9.]//g') + if [ -z "$value" ]; then + continue + fi + if [ -z "$samples" ]; then + samples="$value" + else + samples="${samples},${value}" + fi + last_output="$output" + done + echo "$last_output" | sed 's/^/ /' echo "" - local raw - raw=$(extract_metric "$metric_key" "$output") - local value - value=$(echo "$raw" | sed 's/[^0-9.]//g') - if [ -n "$value" ]; then - json_add_result "$bench" "$lang" "$value" "$raw" + if [ -n "$samples" ]; then + local last_raw + last_raw=$(extract_metric "$metric_key" "$last_output") + json_add_result "$bench" "$lang" "$samples" "$last_raw" fi } diff --git a/docs/.vitepress/theme/BenchmarkBars.vue b/docs/.vitepress/theme/BenchmarkBars.vue index 90f39122..c349c1ee 100644 --- a/docs/.vitepress/theme/BenchmarkBars.vue +++ b/docs/.vitepress/theme/BenchmarkBars.vue @@ -4,6 +4,10 @@ import { ref, onMounted } from 'vue' interface BenchResult { value: number label: string + ci_lo?: number + ci_hi?: number + ci_label?: string + n?: number } interface Benchmark { @@ -46,11 +50,20 @@ function sortEntries(b: Benchmark) { return sorted.map(s => { const unit = b.metric === 'ms' ? 'ms' : 's' const formatted = s.value.toFixed(3) + unit + // CI whisker: where ci_lo / ci_hi sit as a percentage of the bar scale. + const hasCI = s.ci_lo !== undefined && s.ci_hi !== undefined && s.ci_hi > s.ci_lo + const ciLoPct = hasCI ? Math.max(0, Math.round((s.ci_lo! / maxVal) * 100)) : 0 + const ciHiPct = hasCI ? Math.min(100, Math.round((s.ci_hi! / maxVal) * 100)) : 0 return { name: LANG_NAMES[s.key] || s.key, val: formatted, pct: Math.max(3, Math.round((s.value / maxVal) * 100)), hero: s.key === 'chadscript', + hasCI, + ciLoPct, + ciHiPct, + ciLabel: s.ci_label || formatted, + n: s.n || 0, } }) } @@ -93,8 +106,15 @@ onMounted(async () => { :class="{ hero: e.hero }" :style="{ width: e.pct + '%' }" > +
-
{{ e.val }}
+
{{ e.val }}
@@ -181,6 +201,7 @@ onMounted(async () => { background: rgba(255, 255, 255, 0.04); border-radius: 4px; overflow: hidden; + position: relative; } .card-bar { @@ -194,6 +215,26 @@ onMounted(async () => { background: var(--vp-c-brand-1); } +/* 95% bootstrap confidence interval whisker — overlaid on the track, shows + * where the true value could fall. Narrower whisker = more confident. */ +.card-ci { + position: absolute; + top: 5px; + height: 6px; + background: rgba(255, 255, 255, 0.35); + border-left: 1px solid rgba(255, 255, 255, 0.6); + border-right: 1px solid rgba(255, 255, 255, 0.6); + border-radius: 1px; + pointer-events: auto; + transition: left 0.5s cubic-bezier(0.22, 1, 0.36, 1), + width 0.5s cubic-bezier(0.22, 1, 0.36, 1); +} + +.card-ci.hero { + background: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.85); +} + .card-val { width: 52px; font-size: 0.72rem; diff --git a/docs/.vitepress/theme/HeroBenchmarks.vue b/docs/.vitepress/theme/HeroBenchmarks.vue index 302ac88d..5db670f1 100644 --- a/docs/.vitepress/theme/HeroBenchmarks.vue +++ b/docs/.vitepress/theme/HeroBenchmarks.vue @@ -4,6 +4,10 @@ import { ref, onMounted, onUnmounted, computed } from 'vue' interface BenchResult { value: number label: string + ci_lo?: number + ci_hi?: number + ci_label?: string + n?: number } interface Benchmark { diff --git a/docs/benchmarks.md b/docs/benchmarks.md index 00e32960..ca0b2854 100644 --- a/docs/benchmarks.md +++ b/docs/benchmarks.md @@ -2,21 +2,25 @@ ChadScript compiles to native binaries via LLVM IR — no runtime, no JIT warmup, no cold start penalty. -These benchmarks compare ChadScript against C (clang -O2), Go, and Node.js across compute, I/O, and real-world workloads. +These benchmarks compare ChadScript against C (clang -O2 -march=native), Go, and Node.js across compute, I/O, and real-world workloads. ## Methodology -- **Machine**: Linux x86-64, single machine, all runtimes tested sequentially -- **Optimization**: ChadScript and C compiled with `-O2` -- **Timing**: Wall-clock time via `perf_counter` / `clock_gettime` -- **Cold start**: Average of 50 runs +- **Machine**: Apple Silicon (M-series, arm64 native), dedicated hardware, all runtimes tested sequentially +- **Optimization**: ChadScript and C compiled with `-O2 -march=native` +- **Sampling**: Each compute benchmark runs **N=10 times**. The reported value is the **median** of the 10 samples, annotated with a **95% bootstrap confidence interval** (2000 resamples, `random.seed(0xC4AD)` for reproducibility). +- **Ties**: Two languages are treated as tied when their 95% CIs overlap — i.e. the difference between them is not statistically distinguishable at the 95% level. This prevents spurious medal-flipping when jitter produces a 2-3% gap that's inside both intervals. +- **Cold start**: Average of 50 launches (aggregate measurement, not per-sample). +- **Timing**: Wall-clock time via `clock_gettime` / `Date.now()` / `time.Now()`. + +The CI whiskers on the bars show the 95% confidence interval. A narrow whisker means the samples were very consistent; a wide one means the runtime is variable and the point estimate should be trusted less. **Bars whose CIs visibly overlap are statistically tied** — ranking between them is meaningless. Reproduce locally: ```bash -./benchmarks/run.sh +BENCH_RUNS=10 ./benchmarks/run.sh ``` Source code for all benchmarks: [github.com/cs01/ChadScript/tree/main/benchmarks](https://github.com/cs01/ChadScript/tree/main/benchmarks) diff --git a/docs/public/benchmarks-all.json b/docs/public/benchmarks-all.json index 02344442..94d75463 100644 --- a/docs/public/benchmarks-all.json +++ b/docs/public/benchmarks-all.json @@ -1,5 +1,5 @@ { - "timestamp": "2026-04-13T17:42:13Z", + "timestamp": "2026-04-13T21:51:56Z", "benchmarks": { "binarytrees": { "name": "Binary Trees", @@ -8,66 +8,38 @@ "lower_is_better": true, "results": { "c": { - "value": 1.479, - "label": "1.479s" + "value": 0.854, + "ci_lo": 0.8405, + "ci_hi": 0.8675, + "n": 10, + "label": "0.854s", + "ci_label": "0.854s (0.841s\u20130.868s)" }, "chadscript": { - "value": 1.57, - "label": "1.570s" + "value": 0.6035, + "ci_lo": 0.5942, + "ci_hi": 0.6082, + "n": 10, + "label": "0.604s", + "ci_label": "0.604s (0.594s\u20130.608s)" }, "go": { - "value": 2.991, - "label": "2.991s" + "value": 0.8005, + "ci_lo": 0.7965, + "ci_hi": 0.8045, + "n": 10, + "label": "0.800s", + "ci_label": "0.800s (0.796s\u20130.804s)" }, "node": { - "value": 1.484, - "label": "1.484s" - } - }, - "place": 3 - }, - "cligrep": { - "name": "Recursive Grep", - "desc": "cgrep vs grep \u2014 search for 'function' across 5x copies of src/.", - "metric": "s", - "lower_is_better": true, - "results": { - "chadscript": { - "value": 0.021, - "label": "0.021s" - }, - "grep": { - "value": 0.011, - "label": "0.011s" - }, - "node": { - "value": 0.106, - "label": "0.106s" - } - }, - "category": "cli", - "place": 2 - }, - "clihex": { - "name": "Hex Dump", - "desc": "chex vs xxd \u2014 hex dump a 5MB binary file.", - "metric": "s", - "lower_is_better": true, - "results": { - "chadscript": { - "value": 0.477, - "label": "0.477s" - }, - "xxd": { - "value": 0.14, - "label": "0.140s" - }, - "node": { - "value": 1.189, - "label": "1.189s" + "value": 0.368, + "ci_lo": 0.3655, + "ci_hi": 0.37, + "n": 10, + "label": "0.368s", + "ci_label": "0.368s (0.365s\u20130.370s)" } }, - "category": "cli", "place": 2 }, "fibonacci": { @@ -77,20 +49,36 @@ "lower_is_better": true, "results": { "c": { - "value": 0.876, - "label": "0.876s" + "value": 0.4415, + "ci_lo": 0.439, + "ci_hi": 0.445, + "n": 10, + "label": "0.442s", + "ci_label": "0.442s (0.439s\u20130.445s)" }, "chadscript": { - "value": 0.882, - "label": "0.882s" + "value": 0.5165, + "ci_lo": 0.514, + "ci_hi": 0.5191, + "n": 10, + "label": "0.516s", + "ci_label": "0.516s (0.514s\u20130.519s)" }, "go": { - "value": 1.66, - "label": "1.660s" + "value": 0.5725, + "ci_lo": 0.5696, + "ci_hi": 0.579, + "n": 10, + "label": "0.573s", + "ci_label": "0.573s (0.570s\u20130.579s)" }, "node": { - "value": 3.498, - "label": "3.498s" + "value": 1.5025, + "ci_lo": 1.459, + "ci_hi": 1.541, + "n": 10, + "label": "1.502s", + "ci_label": "1.502s (1.459s\u20131.541s)" } }, "place": 2 @@ -102,23 +90,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.134, - "label": "0.134s" + "value": 0.027, + "ci_lo": 0.026, + "ci_hi": 0.03, + "n": 10, + "label": "0.027s", + "ci_label": "0.027s (0.026s\u20130.030s)" }, "chadscript": { - "value": 0.115, - "label": "0.115s" + "value": 0.054, + "ci_lo": 0.0536, + "ci_hi": 0.055, + "n": 10, + "label": "0.054s", + "ci_label": "0.054s (0.054s\u20130.055s)" }, "go": { - "value": 0.106, - "label": "0.106s" + "value": 0.027, + "ci_lo": 0.026, + "ci_hi": 0.03, + "n": 10, + "label": "0.027s", + "ci_label": "0.027s (0.026s\u20130.030s)" }, "node": { - "value": 0.28, - "label": "0.280s" + "value": 0.072, + "ci_lo": 0.071, + "ci_hi": 0.0735, + "n": 10, + "label": "0.072s", + "ci_label": "0.072s (0.071s\u20130.073s)" } }, - "place": 2 + "place": 3 }, "json": { "name": "JSON Parse/Stringify", @@ -127,23 +131,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.005, - "label": "0.005s" + "value": 0.002, + "ci_lo": 0.002, + "ci_hi": 0.003, + "n": 10, + "label": "0.002s", + "ci_label": "0.002s (0.002s\u20130.003s)" }, "chadscript": { - "value": 0.006, - "label": "0.006s" + "value": 0.0024, + "ci_lo": 0.0023, + "ci_hi": 0.0031, + "n": 10, + "label": "0.002s", + "ci_label": "0.002s (0.002s\u20130.003s)" }, "go": { - "value": 0.018, - "label": "0.018s" + "value": 0.007, + "ci_lo": 0.007, + "ci_hi": 0.0075, + "n": 10, + "label": "0.007s", + "ci_label": "0.007s (0.007s\u20130.007s)" }, "node": { - "value": 0.018, - "label": "0.018s" + "value": 0.004, + "ci_lo": 0.004, + "ci_hi": 0.004, + "n": 10, + "label": "0.004s", + "ci_label": "0.004s (0.004s\u20130.004s)" } }, - "place": 2 + "place": 1 }, "matmul": { "name": "Matrix Multiply", @@ -152,22 +172,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.474, - "label": "0.474s" + "value": 0.099, + "ci_lo": 0.098, + "ci_hi": 0.0995, + "n": 10, + "label": "0.099s", + "ci_label": "0.099s (0.098s\u20130.100s)" }, "chadscript": { - "value": 0.768, - "label": "0.768s" + "value": 0.1086, + "ci_lo": 0.1071, + "ci_hi": 0.1094, + "n": 10, + "label": "0.109s", + "ci_label": "0.109s (0.107s\u20130.109s)" }, "go": { - "value": 0.633, - "label": "0.633s" + "value": 0.1, + "ci_lo": 0.0995, + "ci_hi": 0.101, + "n": 10, + "label": "0.100s", + "ci_label": "0.100s (0.100s\u20130.101s)" }, "node": { - "value": 0.432, - "label": "0.432s" + "value": 0.137, + "ci_lo": 0.1363, + "ci_hi": 0.1377, + "n": 10, + "label": "0.137s", + "ci_label": "0.137s (0.136s\u20130.138s)" } - } + }, + "place": 3 }, "montecarlo": { "name": "Monte Carlo Pi", @@ -176,23 +213,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.402, - "label": "0.402s" + "value": 0.2645, + "ci_lo": 0.2632, + "ci_hi": 0.2658, + "n": 10, + "label": "0.265s", + "ci_label": "0.265s (0.263s\u20130.266s)" }, "chadscript": { - "value": 0.432, - "label": "0.432s" + "value": 0.2641, + "ci_lo": 0.2628, + "ci_hi": 0.2654, + "n": 10, + "label": "0.264s", + "ci_label": "0.264s (0.263s\u20130.265s)" }, "go": { - "value": 0.414, - "label": "0.414s" + "value": 0.254, + "ci_lo": 0.2527, + "ci_hi": 0.2555, + "n": 10, + "label": "0.254s", + "ci_label": "0.254s (0.253s\u20130.256s)" }, "node": { - "value": 2.355, - "label": "2.355s" + "value": 2.4855, + "ci_lo": 2.4731, + "ci_hi": 2.4979, + "n": 10, + "label": "2.486s", + "ci_label": "2.486s (2.473s\u20132.498s)" } }, - "place": 3 + "place": 2 }, "nbody": { "name": "N-Body Simulation", @@ -201,23 +254,39 @@ "lower_is_better": true, "results": { "c": { - "value": 1.74, - "label": "1.740s" + "value": 0.7745, + "ci_lo": 0.7706, + "ci_hi": 0.7784, + "n": 10, + "label": "0.774s", + "ci_label": "0.774s (0.771s\u20130.778s)" }, "chadscript": { - "value": 2.188, - "label": "2.188s" + "value": 0.8242, + "ci_lo": 0.8201, + "ci_hi": 0.8283, + "n": 10, + "label": "0.824s", + "ci_label": "0.824s (0.820s\u20130.828s)" }, "go": { - "value": 2.27, - "label": "2.270s" + "value": 0.7845, + "ci_lo": 0.7806, + "ci_hi": 0.7884, + "n": 10, + "label": "0.784s", + "ci_label": "0.784s (0.781s\u20130.788s)" }, "node": { - "value": 2.5, - "label": "2.500s" + "value": 1.089, + "ci_lo": 1.0836, + "ci_hi": 1.0944, + "n": 10, + "label": "1.089s", + "ci_label": "1.089s (1.084s\u20131.094s)" } }, - "place": 2 + "place": 3 }, "sieve": { "name": "Sieve of Eratosthenes", @@ -226,23 +295,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.018, - "label": "0.018s" + "value": 0.008, + "ci_lo": 0.008, + "ci_hi": 0.0095, + "n": 10, + "label": "0.008s", + "ci_label": "0.008s (0.008s\u20130.009s)" }, "chadscript": { - "value": 0.03, - "label": "0.030s" + "value": 0.0119, + "ci_lo": 0.0117, + "ci_hi": 0.013, + "n": 10, + "label": "0.012s", + "ci_label": "0.012s (0.012s\u20130.013s)" }, "go": { - "value": 0.023, - "label": "0.023s" + "value": 0.011, + "ci_lo": 0.0109, + "ci_hi": 0.012, + "n": 10, + "label": "0.011s", + "ci_label": "0.011s (0.011s\u20130.012s)" }, "node": { - "value": 0.041, - "label": "0.041s" + "value": 0.025, + "ci_lo": 0.0249, + "ci_hi": 0.026, + "n": 10, + "label": "0.025s", + "ci_label": "0.025s (0.025s\u20130.026s)" } }, - "place": 3 + "place": 2 }, "sorting": { "name": "Quicksort", @@ -251,20 +336,36 @@ "lower_is_better": true, "results": { "c": { - "value": 0.228, - "label": "0.228s" + "value": 0.121, + "ci_lo": 0.1204, + "ci_hi": 0.123, + "n": 10, + "label": "0.121s", + "ci_label": "0.121s (0.120s\u20130.123s)" }, "chadscript": { - "value": 0.253, - "label": "0.253s" + "value": 0.1404, + "ci_lo": 0.1397, + "ci_hi": 0.1415, + "n": 10, + "label": "0.140s", + "ci_label": "0.140s (0.140s\u20130.141s)" }, "go": { - "value": 0.226, - "label": "0.226s" + "value": 0.125, + "ci_lo": 0.1244, + "ci_hi": 0.126, + "n": 10, + "label": "0.125s", + "ci_label": "0.125s (0.124s\u20130.126s)" }, "node": { - "value": 0.28, - "label": "0.280s" + "value": 0.159, + "ci_lo": 0.1582, + "ci_hi": 0.16, + "n": 10, + "label": "0.159s", + "ci_label": "0.159s (0.158s\u20130.160s)" } }, "place": 3 @@ -276,19 +377,31 @@ "lower_is_better": true, "results": { "c": { - "value": 0.368, - "label": "0.368s" + "value": 0.08, + "ci_lo": 0.079, + "ci_hi": 0.082, + "n": 10, + "label": "0.080s", + "ci_label": "0.080s (0.079s\u20130.082s)" }, "chadscript": { - "value": 0.422, - "label": "0.422s" + "value": 0.0789, + "ci_lo": 0.0783, + "ci_hi": 0.0804, + "n": 10, + "label": "0.079s", + "ci_label": "0.079s (0.078s\u20130.080s)" }, "node": { - "value": 0.437, - "label": "0.437s" + "value": 0.165, + "ci_lo": 0.164, + "ci_hi": 0.1665, + "n": 10, + "label": "0.165s", + "ci_label": "0.165s (0.164s\u20130.167s)" } }, - "place": 2 + "place": 1 }, "startup": { "name": "Cold Start", @@ -297,23 +410,39 @@ "lower_is_better": true, "results": { "c": { - "value": 1.0, - "label": "1.0ms" + "value": 6.8, + "ci_lo": 6.46, + "ci_hi": 7.14, + "n": 1, + "label": "6.8ms", + "ci_label": "6.8ms (6.46ms\u20137.14ms)" }, "chadscript": { - "value": 0.9, - "label": "0.9ms" + "value": 5.9, + "ci_lo": 5.605, + "ci_hi": 6.195, + "n": 1, + "label": "5.9ms", + "ci_label": "5.9ms (5.605ms\u20136.195ms)" }, "go": { - "value": 1.4, - "label": "1.4ms" + "value": 4.5, + "ci_lo": 4.275, + "ci_hi": 4.725, + "n": 1, + "label": "4.5ms", + "ci_label": "4.5ms (4.275ms\u20134.725ms)" }, "node": { - "value": 28.4, - "label": "28.4ms" + "value": 27.4, + "ci_lo": 26.03, + "ci_hi": 28.77, + "n": 1, + "label": "27.4ms", + "ci_label": "27.4ms (26.03ms\u201328.77ms)" } }, - "place": 1 + "place": 2 }, "stringops": { "name": "String Manipulation", @@ -322,22 +451,96 @@ "lower_is_better": true, "results": { "c": { - "value": 0.011, - "label": "0.011s" + "value": 0.006, + "ci_lo": 0.005, + "ci_hi": 0.0075, + "n": 10, + "label": "0.006s", + "ci_label": "0.006s (0.005s\u20130.007s)" + }, + "chadscript": { + "value": 0.0169, + "ci_lo": 0.0167, + "ci_hi": 0.0192, + "n": 10, + "label": "0.017s", + "ci_label": "0.017s (0.017s\u20130.019s)" + }, + "go": { + "value": 0.0075, + "ci_lo": 0.007, + "ci_hi": 0.009, + "n": 10, + "label": "0.007s", + "ci_label": "0.007s (0.007s\u20130.009s)" + }, + "node": { + "value": 0.012, + "ci_lo": 0.0119, + "ci_hi": 0.0121, + "n": 10, + "label": "0.012s", + "ci_label": "0.012s (0.012s\u20130.012s)" + } + }, + "place": 4 + }, + "stringsearch": { + "name": "String Search", + "desc": "Recursive directory search for 'console.log' in src/.", + "metric": "s", + "lower_is_better": true, + "results": { + "c": { + "value": 0.005, + "ci_lo": 0.005, + "ci_hi": 0.0075, + "n": 10, + "label": "0.005s", + "ci_label": "0.005s (0.005s\u20130.007s)" }, "chadscript": { - "value": 0.05, - "label": "0.050s" + "value": 0.0202, + "ci_lo": 0.0195, + "ci_hi": 0.0225, + "n": 10, + "label": "0.020s", + "ci_label": "0.020s (0.019s\u20130.022s)" }, "go": { - "value": 0.02, - "label": "0.020s" + "value": 0.005, + "ci_lo": 0.005, + "ci_hi": 0.006, + "n": 10, + "label": "0.005s", + "ci_label": "0.005s (0.005s\u20130.006s)" }, "node": { - "value": 0.042, - "label": "0.042s" + "value": 0.01, + "ci_lo": 0.01, + "ci_hi": 0.01, + "n": 10, + "label": "0.010s", + "ci_label": "0.010s (0.010s\u20130.010s)" + }, + "grep": { + "value": 0.025, + "ci_lo": 0.024, + "ci_hi": 0.0251, + "n": 10, + "label": "0.025s", + "ci_label": "0.025s (0.024s\u20130.025s)" + }, + "ripgrep": { + "value": 0.009, + "ci_lo": 0.009, + "ci_hi": 0.01, + "n": 10, + "label": "0.009s", + "ci_label": "0.009s (0.009s\u20130.010s)" } - } + }, + "place": 5 } } } \ No newline at end of file diff --git a/docs/public/benchmarks.json b/docs/public/benchmarks.json index b25e535e..73d13f50 100644 --- a/docs/public/benchmarks.json +++ b/docs/public/benchmarks.json @@ -1,149 +1,169 @@ { - "timestamp": "2026-04-13T17:42:13Z", + "timestamp": "2026-04-13T21:51:56Z", "benchmarks": { - "binarytrees": { - "name": "Binary Trees", - "desc": "Build/check/discard binary trees of depth 18.", + "fibonacci": { + "name": "Fibonacci", + "desc": "fib(42) naive recursion.", "metric": "s", "lower_is_better": true, "results": { "c": { - "value": 1.479, - "label": "1.479s" + "value": 0.4415, + "ci_lo": 0.439, + "ci_hi": 0.445, + "n": 10, + "label": "0.442s", + "ci_label": "0.442s (0.439s\u20130.445s)" }, "chadscript": { - "value": 1.57, - "label": "1.570s" + "value": 0.5165, + "ci_lo": 0.514, + "ci_hi": 0.5191, + "n": 10, + "label": "0.516s", + "ci_label": "0.516s (0.514s\u20130.519s)" }, "go": { - "value": 2.991, - "label": "2.991s" + "value": 0.5725, + "ci_lo": 0.5696, + "ci_hi": 0.579, + "n": 10, + "label": "0.573s", + "ci_label": "0.573s (0.570s\u20130.579s)" }, "node": { - "value": 1.484, - "label": "1.484s" + "value": 1.5025, + "ci_lo": 1.459, + "ci_hi": 1.541, + "n": 10, + "label": "1.502s", + "ci_label": "1.502s (1.459s\u20131.541s)" } }, - "place": 3 - }, - "cligrep": { - "name": "Recursive Grep", - "desc": "cgrep vs grep \u2014 search for 'function' across 5x copies of src/.", - "metric": "s", - "lower_is_better": true, - "results": { - "chadscript": { - "value": 0.021, - "label": "0.021s" - }, - "grep": { - "value": 0.011, - "label": "0.011s" - }, - "node": { - "value": 0.106, - "label": "0.106s" - } - }, - "category": "cli", "place": 2 }, - "clihex": { - "name": "Hex Dump", - "desc": "chex vs xxd \u2014 hex dump a 5MB binary file.", - "metric": "s", - "lower_is_better": true, - "results": { - "chadscript": { - "value": 0.477, - "label": "0.477s" - }, - "xxd": { - "value": 0.14, - "label": "0.140s" - }, - "node": { - "value": 1.189, - "label": "1.189s" - } - }, - "category": "cli", - "place": 2 - }, - "fibonacci": { - "name": "Fibonacci", - "desc": "fib(42) naive recursion.", + "fileio": { + "name": "File I/O", + "desc": "Write and read ~100MB to /tmp.", "metric": "s", "lower_is_better": true, "results": { "c": { - "value": 0.876, - "label": "0.876s" + "value": 0.027, + "ci_lo": 0.026, + "ci_hi": 0.03, + "n": 10, + "label": "0.027s", + "ci_label": "0.027s (0.026s\u20130.030s)" }, "chadscript": { - "value": 0.882, - "label": "0.882s" + "value": 0.054, + "ci_lo": 0.0536, + "ci_hi": 0.055, + "n": 10, + "label": "0.054s", + "ci_label": "0.054s (0.054s\u20130.055s)" }, "go": { - "value": 1.66, - "label": "1.660s" + "value": 0.027, + "ci_lo": 0.026, + "ci_hi": 0.03, + "n": 10, + "label": "0.027s", + "ci_label": "0.027s (0.026s\u20130.030s)" }, "node": { - "value": 3.498, - "label": "3.498s" + "value": 0.072, + "ci_lo": 0.071, + "ci_hi": 0.0735, + "n": 10, + "label": "0.072s", + "ci_label": "0.072s (0.071s\u20130.073s)" } }, - "place": 2 + "place": 3 }, - "fileio": { - "name": "File I/O", - "desc": "Write and read ~100MB to /tmp.", + "json": { + "name": "JSON Parse/Stringify", + "desc": "Parse 10K JSON objects, stringify back.", "metric": "s", "lower_is_better": true, "results": { "c": { - "value": 0.134, - "label": "0.134s" + "value": 0.002, + "ci_lo": 0.002, + "ci_hi": 0.003, + "n": 10, + "label": "0.002s", + "ci_label": "0.002s (0.002s\u20130.003s)" }, "chadscript": { - "value": 0.115, - "label": "0.115s" + "value": 0.0024, + "ci_lo": 0.0023, + "ci_hi": 0.0031, + "n": 10, + "label": "0.002s", + "ci_label": "0.002s (0.002s\u20130.003s)" }, "go": { - "value": 0.106, - "label": "0.106s" + "value": 0.007, + "ci_lo": 0.007, + "ci_hi": 0.0075, + "n": 10, + "label": "0.007s", + "ci_label": "0.007s (0.007s\u20130.007s)" }, "node": { - "value": 0.28, - "label": "0.280s" + "value": 0.004, + "ci_lo": 0.004, + "ci_hi": 0.004, + "n": 10, + "label": "0.004s", + "ci_label": "0.004s (0.004s\u20130.004s)" } }, - "place": 2 + "place": 1 }, - "json": { - "name": "JSON Parse/Stringify", - "desc": "Parse 10K JSON objects, stringify back.", + "matmul": { + "name": "Matrix Multiply", + "desc": "512x512 double-precision matrix multiply.", "metric": "s", "lower_is_better": true, "results": { "c": { - "value": 0.005, - "label": "0.005s" + "value": 0.099, + "ci_lo": 0.098, + "ci_hi": 0.0995, + "n": 10, + "label": "0.099s", + "ci_label": "0.099s (0.098s\u20130.100s)" }, "chadscript": { - "value": 0.006, - "label": "0.006s" + "value": 0.1086, + "ci_lo": 0.1071, + "ci_hi": 0.1094, + "n": 10, + "label": "0.109s", + "ci_label": "0.109s (0.107s\u20130.109s)" }, "go": { - "value": 0.018, - "label": "0.018s" + "value": 0.1, + "ci_lo": 0.0995, + "ci_hi": 0.101, + "n": 10, + "label": "0.100s", + "ci_label": "0.100s (0.100s\u20130.101s)" }, "node": { - "value": 0.018, - "label": "0.018s" + "value": 0.137, + "ci_lo": 0.1363, + "ci_hi": 0.1377, + "n": 10, + "label": "0.137s", + "ci_label": "0.137s (0.136s\u20130.138s)" } }, - "place": 2 + "place": 3 }, "montecarlo": { "name": "Monte Carlo Pi", @@ -152,23 +172,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.402, - "label": "0.402s" + "value": 0.2645, + "ci_lo": 0.2632, + "ci_hi": 0.2658, + "n": 10, + "label": "0.265s", + "ci_label": "0.265s (0.263s\u20130.266s)" }, "chadscript": { - "value": 0.432, - "label": "0.432s" + "value": 0.2641, + "ci_lo": 0.2628, + "ci_hi": 0.2654, + "n": 10, + "label": "0.264s", + "ci_label": "0.264s (0.263s\u20130.265s)" }, "go": { - "value": 0.414, - "label": "0.414s" + "value": 0.254, + "ci_lo": 0.2527, + "ci_hi": 0.2555, + "n": 10, + "label": "0.254s", + "ci_label": "0.254s (0.253s\u20130.256s)" }, "node": { - "value": 2.355, - "label": "2.355s" + "value": 2.4855, + "ci_lo": 2.4731, + "ci_hi": 2.4979, + "n": 10, + "label": "2.486s", + "ci_label": "2.486s (2.473s\u20132.498s)" } }, - "place": 3 + "place": 2 }, "nbody": { "name": "N-Body Simulation", @@ -177,23 +213,39 @@ "lower_is_better": true, "results": { "c": { - "value": 1.74, - "label": "1.740s" + "value": 0.7745, + "ci_lo": 0.7706, + "ci_hi": 0.7784, + "n": 10, + "label": "0.774s", + "ci_label": "0.774s (0.771s\u20130.778s)" }, "chadscript": { - "value": 2.188, - "label": "2.188s" + "value": 0.8242, + "ci_lo": 0.8201, + "ci_hi": 0.8283, + "n": 10, + "label": "0.824s", + "ci_label": "0.824s (0.820s\u20130.828s)" }, "go": { - "value": 2.27, - "label": "2.270s" + "value": 0.7845, + "ci_lo": 0.7806, + "ci_hi": 0.7884, + "n": 10, + "label": "0.784s", + "ci_label": "0.784s (0.781s\u20130.788s)" }, "node": { - "value": 2.5, - "label": "2.500s" + "value": 1.089, + "ci_lo": 1.0836, + "ci_hi": 1.0944, + "n": 10, + "label": "1.089s", + "ci_label": "1.089s (1.084s\u20131.094s)" } }, - "place": 2 + "place": 3 }, "sieve": { "name": "Sieve of Eratosthenes", @@ -202,23 +254,39 @@ "lower_is_better": true, "results": { "c": { - "value": 0.018, - "label": "0.018s" + "value": 0.008, + "ci_lo": 0.008, + "ci_hi": 0.0095, + "n": 10, + "label": "0.008s", + "ci_label": "0.008s (0.008s\u20130.009s)" }, "chadscript": { - "value": 0.03, - "label": "0.030s" + "value": 0.0119, + "ci_lo": 0.0117, + "ci_hi": 0.013, + "n": 10, + "label": "0.012s", + "ci_label": "0.012s (0.012s\u20130.013s)" }, "go": { - "value": 0.023, - "label": "0.023s" + "value": 0.011, + "ci_lo": 0.0109, + "ci_hi": 0.012, + "n": 10, + "label": "0.011s", + "ci_label": "0.011s (0.011s\u20130.012s)" }, "node": { - "value": 0.041, - "label": "0.041s" + "value": 0.025, + "ci_lo": 0.0249, + "ci_hi": 0.026, + "n": 10, + "label": "0.025s", + "ci_label": "0.025s (0.025s\u20130.026s)" } }, - "place": 3 + "place": 2 }, "sorting": { "name": "Quicksort", @@ -227,20 +295,36 @@ "lower_is_better": true, "results": { "c": { - "value": 0.228, - "label": "0.228s" + "value": 0.121, + "ci_lo": 0.1204, + "ci_hi": 0.123, + "n": 10, + "label": "0.121s", + "ci_label": "0.121s (0.120s\u20130.123s)" }, "chadscript": { - "value": 0.253, - "label": "0.253s" + "value": 0.1404, + "ci_lo": 0.1397, + "ci_hi": 0.1415, + "n": 10, + "label": "0.140s", + "ci_label": "0.140s (0.140s\u20130.141s)" }, "go": { - "value": 0.226, - "label": "0.226s" + "value": 0.125, + "ci_lo": 0.1244, + "ci_hi": 0.126, + "n": 10, + "label": "0.125s", + "ci_label": "0.125s (0.124s\u20130.126s)" }, "node": { - "value": 0.28, - "label": "0.280s" + "value": 0.159, + "ci_lo": 0.1582, + "ci_hi": 0.16, + "n": 10, + "label": "0.159s", + "ci_label": "0.159s (0.158s\u20130.160s)" } }, "place": 3 @@ -252,19 +336,31 @@ "lower_is_better": true, "results": { "c": { - "value": 0.368, - "label": "0.368s" + "value": 0.08, + "ci_lo": 0.079, + "ci_hi": 0.082, + "n": 10, + "label": "0.080s", + "ci_label": "0.080s (0.079s\u20130.082s)" }, "chadscript": { - "value": 0.422, - "label": "0.422s" + "value": 0.0789, + "ci_lo": 0.0783, + "ci_hi": 0.0804, + "n": 10, + "label": "0.079s", + "ci_label": "0.079s (0.078s\u20130.080s)" }, "node": { - "value": 0.437, - "label": "0.437s" + "value": 0.165, + "ci_lo": 0.164, + "ci_hi": 0.1665, + "n": 10, + "label": "0.165s", + "ci_label": "0.165s (0.164s\u20130.167s)" } }, - "place": 2 + "place": 1 }, "startup": { "name": "Cold Start", @@ -273,23 +369,178 @@ "lower_is_better": true, "results": { "c": { - "value": 1.0, - "label": "1.0ms" + "value": 6.8, + "ci_lo": 6.46, + "ci_hi": 7.14, + "n": 1, + "label": "6.8ms", + "ci_label": "6.8ms (6.46ms\u20137.14ms)" }, "chadscript": { - "value": 0.9, - "label": "0.9ms" + "value": 5.9, + "ci_lo": 5.605, + "ci_hi": 6.195, + "n": 1, + "label": "5.9ms", + "ci_label": "5.9ms (5.605ms\u20136.195ms)" }, "go": { - "value": 1.4, - "label": "1.4ms" + "value": 4.5, + "ci_lo": 4.275, + "ci_hi": 4.725, + "n": 1, + "label": "4.5ms", + "ci_label": "4.5ms (4.275ms\u20134.725ms)" }, "node": { - "value": 28.4, - "label": "28.4ms" + "value": 27.4, + "ci_lo": 26.03, + "ci_hi": 28.77, + "n": 1, + "label": "27.4ms", + "ci_label": "27.4ms (26.03ms\u201328.77ms)" } }, - "place": 1 + "place": 2 + }, + "stringops": { + "name": "String Manipulation", + "desc": "Concatenate 100K strings, split, toUpperCase, join.", + "metric": "s", + "lower_is_better": true, + "results": { + "c": { + "value": 0.006, + "ci_lo": 0.005, + "ci_hi": 0.0075, + "n": 10, + "label": "0.006s", + "ci_label": "0.006s (0.005s\u20130.007s)" + }, + "chadscript": { + "value": 0.0169, + "ci_lo": 0.0167, + "ci_hi": 0.0192, + "n": 10, + "label": "0.017s", + "ci_label": "0.017s (0.017s\u20130.019s)" + }, + "go": { + "value": 0.0075, + "ci_lo": 0.007, + "ci_hi": 0.009, + "n": 10, + "label": "0.007s", + "ci_label": "0.007s (0.007s\u20130.009s)" + }, + "node": { + "value": 0.012, + "ci_lo": 0.0119, + "ci_hi": 0.0121, + "n": 10, + "label": "0.012s", + "ci_label": "0.012s (0.012s\u20130.012s)" + } + }, + "place": 4 + }, + "stringsearch": { + "name": "String Search", + "desc": "Recursive directory search for 'console.log' in src/.", + "metric": "s", + "lower_is_better": true, + "results": { + "c": { + "value": 0.005, + "ci_lo": 0.005, + "ci_hi": 0.0075, + "n": 10, + "label": "0.005s", + "ci_label": "0.005s (0.005s\u20130.007s)" + }, + "chadscript": { + "value": 0.0202, + "ci_lo": 0.0195, + "ci_hi": 0.0225, + "n": 10, + "label": "0.020s", + "ci_label": "0.020s (0.019s\u20130.022s)" + }, + "go": { + "value": 0.005, + "ci_lo": 0.005, + "ci_hi": 0.006, + "n": 10, + "label": "0.005s", + "ci_label": "0.005s (0.005s\u20130.006s)" + }, + "node": { + "value": 0.01, + "ci_lo": 0.01, + "ci_hi": 0.01, + "n": 10, + "label": "0.010s", + "ci_label": "0.010s (0.010s\u20130.010s)" + }, + "grep": { + "value": 0.025, + "ci_lo": 0.024, + "ci_hi": 0.0251, + "n": 10, + "label": "0.025s", + "ci_label": "0.025s (0.024s\u20130.025s)" + }, + "ripgrep": { + "value": 0.009, + "ci_lo": 0.009, + "ci_hi": 0.01, + "n": 10, + "label": "0.009s", + "ci_label": "0.009s (0.009s\u20130.010s)" + } + }, + "place": 5 + }, + "binarytrees": { + "name": "Binary Trees", + "desc": "Build/check/discard binary trees of depth 18.", + "metric": "s", + "lower_is_better": true, + "results": { + "c": { + "value": 0.854, + "ci_lo": 0.8405, + "ci_hi": 0.8675, + "n": 10, + "label": "0.854s", + "ci_label": "0.854s (0.841s\u20130.868s)" + }, + "chadscript": { + "value": 0.6035, + "ci_lo": 0.5942, + "ci_hi": 0.6082, + "n": 10, + "label": "0.604s", + "ci_label": "0.604s (0.594s\u20130.608s)" + }, + "go": { + "value": 0.8005, + "ci_lo": 0.7965, + "ci_hi": 0.8045, + "n": 10, + "label": "0.800s", + "ci_label": "0.800s (0.796s\u20130.804s)" + }, + "node": { + "value": 0.368, + "ci_lo": 0.3655, + "ci_hi": 0.37, + "n": 10, + "label": "0.368s", + "ci_label": "0.368s (0.365s\u20130.370s)" + } + }, + "place": 2 } } } \ No newline at end of file