diff --git a/bench/web/components/Header.test.tsx b/bench/web/components/Header.test.tsx index c2910e9f..4e5b7c69 100644 --- a/bench/web/components/Header.test.tsx +++ b/bench/web/components/Header.test.tsx @@ -36,6 +36,12 @@ describe('Header (server-rendered chrome)', () => { expect(matches).toHaveLength(2); }); + it('links the Vortex logo to vortex.dev', () => { + expect(html).toContain( + '', + ); + }); + it('renders the theme toggle with the v3 server-default label', () => { expect(html).toContain('data-role="theme-toggle"'); expect(html).toContain('data-next-theme="light"'); diff --git a/bench/web/components/Header.tsx b/bench/web/components/Header.tsx index 81804bce..24e17525 100644 --- a/bench/web/components/Header.tsx +++ b/bench/web/components/Header.tsx @@ -3,7 +3,6 @@ 'use client'; -import Link from 'next/link'; import { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { FilterBar } from '@/components/FilterBar'; @@ -24,7 +23,8 @@ import { effectiveTheme } from '@/lib/theme'; * `server/src/html/render.rs::site_header` plus the section-18 header controls * of `chart-init.js`: the hamburger-toggled mobile nav panel (expand/collapse * all, the global filter dropdown, and the mobile-only GitHub link), the - * theme-aware logo, the desktop GitHub link, and the theme toggle. + * theme-aware logo (a link to vortex.dev), the desktop GitHub link, and the + * theme toggle. * * Expand/Collapse All writes `details.open` on every group disclosure * directly, then schedules one write of the open set into the URL fragment @@ -139,7 +139,7 @@ export function Header({ > - + - +

Vortex Benchmarks

diff --git a/src/components/logo-banner/index.tsx b/src/components/logo-banner/index.tsx index 3ce364d3..8dcf7899 100644 --- a/src/components/logo-banner/index.tsx +++ b/src/components/logo-banner/index.tsx @@ -89,7 +89,7 @@ export function LogoBanner({ className }: { className?: string | undefined }) { /> {soon && ( - Coming soon + In proposal )} diff --git a/src/components/logo-banner/logos.ts b/src/components/logo-banner/logos.ts index fe7fd82c..547e2ea2 100644 --- a/src/components/logo-banner/logos.ts +++ b/src/components/logo-banner/logos.ts @@ -24,7 +24,7 @@ export type Logo = { height: number; /** The owner's page about its Vortex use, else its homepage. */ href: string; - /** Tagged "Coming soon": its Vortex support has not shipped yet. */ + /** Tagged "In proposal": its Vortex support is proposed, not shipped. */ soon?: true; }; @@ -37,7 +37,7 @@ export type Logo = { // links to the owner's own page that mentions Vortex where there is one // (docs, a post or a list of users), else to the owner's homepage. Dash0 // links to the Vortex post by Polar Signals, which it acquired. Apache -// Iceberg is tagged "Coming soon" until its Vortex support ships. +// Iceberg is tagged "In proposal" until its Vortex support ships. export const LOGOS: readonly Logo[] = [ { name: "Microsoft", @@ -74,13 +74,6 @@ export const LOGOS: readonly Logo[] = [ height: 26, href: "https://spice.ai/blog/vortex-at-spice-ai-the-columnar-format-for-data-intensive-workloads" }, - { - name: "LangChain", - image: langchain, - width: 136, - height: 25, - href: "https://www.langchain.com/blog/introducing-smithdb" - }, { name: "DatologyAI", image: datologyai, @@ -95,6 +88,13 @@ export const LOGOS: readonly Logo[] = [ height: 23, href: "https://www.polarsignals.com/blog/posts/2025/11/25/interface-parquet-vortex" }, + { + name: "LangChain", + image: langchain, + width: 136, + height: 25, + href: "https://www.langchain.com/blog/introducing-smithdb" + }, { name: "Milvus", image: milvus, diff --git a/src/lib/bench-summary.ts b/src/lib/bench-summary.ts index c9870543..b656f696 100644 --- a/src/lib/bench-summary.ts +++ b/src/lib/bench-summary.ts @@ -135,19 +135,19 @@ const SOURCES: (Source | Panel)[] = [ }, GPU_PANEL, { - title: "Random access, NVMe, cold", + title: "Random access, NVMe, hot", unit: "ms", kind: "speed", better: "lower", group: "Random Access (NVMe)", - rankings: (s) => s.coldRankings, + rankings: (s) => s.hotRankings, name: (f) => f, score: "score", systems: WITH_ARROW, // Bench sums a dataset's charts ("taxi", "taxi/correlated", // "taxi/uniform") into one time per dataset. times: { - series: (f) => `${f}:cold`, + series: (f) => `${f}:hot`, bucket: (chart) => chart.split("/")[0] ?? chart } }, diff --git a/tests/smoke.spec.ts b/tests/smoke.spec.ts index df58c1ca..579d973d 100644 --- a/tests/smoke.spec.ts +++ b/tests/smoke.spec.ts @@ -260,7 +260,7 @@ test.describe("home bands", () => { expect(names.slice(0, 3)).toEqual(["Microsoft", "Palantir", "Spiral"]); expect(new Set(names).size).toBe(names.length); await expect( - banner.getByRole("link", { name: "Apache Iceberg Coming soon" }) + banner.getByRole("link", { name: "Apache Iceberg In proposal" }) ).toHaveClass("is-soon"); // Every mark loads. for (const img of await banner.getByRole("img").all()) @@ -1026,7 +1026,7 @@ test.describe("logo banner under reduced motion", () => { .locator('section[aria-label="Ecosystem"] .vx-logos-set') .first(); expect(await set.locator("img").count()).toBeGreaterThanOrEqual(16); - // A "Coming soon" tag hangs past its logo, so the tags are checked too. + // An "In proposal" tag hangs past its logo, so the tags are checked too. const marks = set.locator(":is(img, .vx-logos-soon)"); for (const box of await marks.evaluateAll((els) => els.map((e) => e.getBoundingClientRect().toJSON()) diff --git a/tests/unit/bench-summary.test.ts b/tests/unit/bench-summary.test.ts index 640f90e8..cf303484 100644 --- a/tests/unit/bench-summary.test.ts +++ b/tests/unit/bench-summary.test.ts @@ -30,7 +30,8 @@ const PAYLOAD = fixture("bench-groups.json") as { }; // bench.vortex.dev/api/group/{slug}?n=20 for the two time panels' groups, read // at the same time, cut down to the series the card reads (and one it does -// not) and their last five commits. +// not) and their last five commits. Random access's hot series were read on +// 30 Oct 2026, from the same two commits as the rest. const CHARTS = { Clickbench: fixture("bench-group-clickbench.json"), "Random Access (NVMe)": fixture("bench-group-random-access-nvme.json") @@ -60,18 +61,19 @@ const charts = () => >; // Each system's geomean time in ms, computed from the fixture apart from the -// site's code (Python, 29 Oct 2026): the latest time per ClickBench query, -// and per random-access dataset the sum of its charts' latest times. +// site's code (Python, 29 Oct 2026; random access, 30 Oct): the latest time +// per ClickBench query, and per random-access dataset the sum of its charts' +// latest hot times. const CLICKBENCH_MS = { Vortex: 42.24600623816063, Parquet: 65.621614465414, Lance: 578.6306006236966 }; const RANDOM_ACCESS_MS = { - Vortex: 2.222937250565255, - Parquet: 70.3627371272798, - Lance: 3.5349948744551765, - Arrow: 3.716574078241951 + Vortex: 0.7290522397517741, + Parquet: 70.61301694616571, + Lance: 2.1526584338038828, + Arrow: 3.7780608403173668 }; // The six panels from the fixtures. The ratio panels carry bench's published @@ -127,7 +129,7 @@ const PANELS: Panel[] = [ }, GPU_PANEL, { - title: "Random access, NVMe, cold", + title: "Random access, NVMe, hot", unit: "ms", kind: "speed", better: "lower", @@ -181,7 +183,7 @@ describe("panelsFrom", () => { }; for (const [i, g, key, name] of [ [2, "Clickbench", "rankings", (f: string) => `datafusion:${f}`], - [4, "Random Access (NVMe)", "coldRankings", (f: string) => f] + [4, "Random Access (NVMe)", "hotRankings", (f: string) => f] ] as const) { const rows = panels?.[i]?.rows ?? []; const ms = (s: string) => rows.find((r) => r.system === s)?.score ?? NaN; @@ -210,10 +212,8 @@ describe("panelsFrom", () => { it("drops a time that bench does not score", () => { const gs = groups(); - const cold = group(gs, "Random Access (NVMe)").summary; - cold.coldRankings = (cold.coldRankings ?? []).filter( - (r) => r.name !== "lance" - ); + const hot = group(gs, "Random Access (NVMe)").summary; + hot.hotRankings = (hot.hotRankings ?? []).filter((r) => r.name !== "lance"); assert.deepEqual(panelsFrom(gs, charts())?.[4]?.rows[2], { system: "Lance", score: null, @@ -341,7 +341,7 @@ describe("panelsFrom", () => { it("gives null when a group reports none of the systems it shows", () => { const gs = groups(); - group(gs, "Random Access (NVMe)").summary.coldRankings = []; + group(gs, "Random Access (NVMe)").summary.hotRankings = []; assert.equal(panelsFrom(gs, charts()), null); // Arrow alone is shown only where bench runs it, so a scan ranking that // listed only Arrow still counts as none. diff --git a/tests/unit/benchmark-card.test.tsx b/tests/unit/benchmark-card.test.tsx index c72aba72..2d3fae65 100644 --- a/tests/unit/benchmark-card.test.tsx +++ b/tests/unit/benchmark-card.test.tsx @@ -31,7 +31,7 @@ describe("BenchPanel", () => { it("matches renderPanel for a missing and a partial system", () => { const panel: Panel = { - title: "Random access, NVMe, cold", + title: "Random access, NVMe, hot", unit: "ms", kind: "speed", better: "lower", @@ -115,7 +115,7 @@ describe("BenchmarkCard", () => { }); // Note 34: the bars and the big figure read the same numbers, so NVMe's - // bars give the 32× above them. Note 63: time panels show geomean ms, each + // bars give the 97× above them. Note 63: time panels show geomean ms, each // value carries a short unit, and below 2× the figure is a percentage. it("ends each bar in its value and unit, keeps the full unit for screen readers and hover, and the bars agree with the figure", () => { assert.ok(PANELS); @@ -133,7 +133,7 @@ describe("BenchmarkCard", () => { ["1.58×", "1.00×", "0.53×"], ["42.25 ms", "65.62 ms", "578.63 ms"], ["17.00 ms", "65.88 ms", "N/A"], - ["2.22 ms", "3.53 ms", "3.72 ms", "70.36 ms"], + ["0.73 ms", "2.15 ms", "3.78 ms", "70.61 ms"], ["1×", "1.07×", "1.99×", "5.59×"] ].flat() ); @@ -150,11 +150,11 @@ describe("BenchmarkCard", () => { ["1.58× Parquet", "1.00× Parquet", "0.53× Parquet"], ["42.25 ms", "65.62 ms", "578.63 ms"], ["17.00 ms", "65.88 ms", "not available, no cuDF integration"], - ["2.22 ms", "3.53 ms", "3.72 ms", "70.36 ms"], + ["0.73 ms", "2.15 ms", "3.78 ms", "70.61 ms"], ["1×", "1.07×", "1.99×", "5.59×"] ].flat() ); - assert.match(html, /
/); + assert.match(html, /
/); const big = [ ...html.matchAll( /class="vx-bench-big">([^<]*)<\/span> ([^<]*) { "58% faster than Parquet", "55% faster than Parquet", "3.9× faster than Parquet", - "32× faster than Parquet", + "97× faster than Parquet", "7% larger than Parquet" ]); // Each panel's value column fits its longest value, so its bars share a scale. diff --git a/tests/unit/fixtures/bench-group-random-access-nvme.json b/tests/unit/fixtures/bench-group-random-access-nvme.json index a717acae..e1712abb 100644 --- a/tests/unit/fixtures/bench-group-random-access-nvme.json +++ b/tests/unit/fixtures/bench-group-random-access-nvme.json @@ -7,11 +7,11 @@ "display_name": "feature-vectors/correlated", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [1209291, 1236252, null, null, null], - "parquet:cold": [10781974, 10784105, null, null, null], - "lance:cold": [951081, 952246, null, null, null], - "arrow-ipc:cold": [2044002, 3730718, null, null, null], - "vortex-file-compressed:hot": [110418, 107654, null, null, null] + "vortex-file-compressed:hot": [110418, 107654, null, null, null], + "parquet:hot": [10354321, 10430477, null, null, null], + "lance:hot": [154771, 153570, null, null, null], + "arrow-ipc:hot": [2819676, 1335129, null, null, null], + "vortex-file-compressed:cold": [1209291, 1236252, null, null, null] } }, { @@ -20,11 +20,11 @@ "display_name": "feature-vectors/uniform", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [2356769, 2374317, null, null, null], - "parquet:cold": [137559887, 133802206, null, null, null], - "lance:cold": [1761123, 1810772, null, null, null], - "arrow-ipc:cold": [49861004, 35951190, null, null, null], - "vortex-file-compressed:hot": [984853, 1023791, null, null, null] + "vortex-file-compressed:hot": [984853, 1023791, null, null, null], + "parquet:hot": [137546685, 137992286, null, null, null], + "lance:hot": [982165, 998759, null, null, null], + "arrow-ipc:hot": [49583183, 52187750, null, null, null], + "vortex-file-compressed:cold": [2356769, 2374317, null, null, null] } }, { @@ -33,11 +33,11 @@ "display_name": "nested-lists/correlated", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [336783, 352557, null, null, null], - "parquet:cold": [4912625, 4893052, null, null, null], - "lance:cold": [429895, 436339, null, null, null], - "arrow-ipc:cold": [100073, 103886, null, null, null], - "vortex-file-compressed:hot": [98244, 96734, null, null, null] + "vortex-file-compressed:hot": [98244, 96734, null, null, null], + "parquet:hot": [4740464, 4832850, null, null, null], + "lance:hot": [113010, 115638, null, null, null], + "arrow-ipc:hot": [56383, 55985, null, null, null], + "vortex-file-compressed:cold": [336783, 352557, null, null, null] } }, { @@ -46,11 +46,11 @@ "display_name": "nested-lists/uniform", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [850357, 943825, null, null, null], - "parquet:cold": [38286166, 38424139, null, null, null], - "lance:cold": [1318625, 1346258, null, null, null], - "arrow-ipc:cold": [1121795, 1265763, null, null, null], - "vortex-file-compressed:hot": [423955, 421067, null, null, null] + "vortex-file-compressed:hot": [423955, 421067, null, null, null], + "parquet:hot": [39569156, 38667572, null, null, null], + "lance:hot": [841391, 848580, null, null, null], + "arrow-ipc:hot": [1081353, 1232824, null, null, null], + "vortex-file-compressed:cold": [850357, 943825, null, null, null] } }, { @@ -59,11 +59,11 @@ "display_name": "nested-structs/correlated", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [422279, 420708, null, null, null], - "parquet:cold": [9404889, 9615878, null, null, null], - "lance:cold": [490547, 484930, null, null, null], - "arrow-ipc:cold": [90364, 89430, null, null, null], - "vortex-file-compressed:hot": [120881, 120410, null, null, null] + "vortex-file-compressed:hot": [120881, 120410, null, null, null], + "parquet:hot": [9291171, 9459598, null, null, null], + "lance:hot": [216551, 214361, null, null, null], + "arrow-ipc:hot": [51535, 51409, null, null, null], + "vortex-file-compressed:cold": [422279, 420708, null, null, null] } }, { @@ -72,11 +72,11 @@ "display_name": "nested-structs/uniform", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [620198, 622078, null, null, null], - "parquet:cold": [37850813, 37834446, null, null, null], - "lance:cold": [2558267, 2439329, null, null, null], - "arrow-ipc:cold": [887290, 938270, null, null, null], - "vortex-file-compressed:hot": [265075, 250281, null, null, null] + "vortex-file-compressed:hot": [265075, 250281, null, null, null], + "parquet:hot": [37906744, 37750759, null, null, null], + "lance:hot": [2194352, 2180167, null, null, null], + "arrow-ipc:hot": [835952, 892694, null, null, null], + "vortex-file-compressed:cold": [620198, 622078, null, null, null] } }, { @@ -85,11 +85,11 @@ "display_name": "taxi", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [927198, 922392, null, null, null], - "parquet:cold": [17812885, 17913316, null, null, null], - "lance:cold": [1251132, 1249864, null, null, null], - "arrow-ipc:cold": [168412, 167889, null, null, null], - "vortex-file-compressed:hot": [222312, 218772, null, null, null] + "vortex-file-compressed:hot": [222312, 218772, null, null, null], + "parquet:hot": [17830822, 17437418, null, null, null], + "lance:hot": [432395, 439012, null, null, null], + "arrow-ipc:hot": [70759, 73165, null, null, null], + "vortex-file-compressed:cold": [927198, 922392, null, null, null] } }, { @@ -98,11 +98,11 @@ "display_name": "taxi/correlated", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [1092553, 1101477, null, null, null], - "parquet:cold": [24981353, 25099885, null, null, null], - "lance:cold": [1631034, 1631876, null, null, null], - "arrow-ipc:cold": [228782, 221890, null, null, null], - "vortex-file-compressed:hot": [257170, 252184, null, null, null] + "vortex-file-compressed:hot": [257170, 252184, null, null, null], + "parquet:hot": [25038867, 24779262, null, null, null], + "lance:hot": [659640, 632610, null, null, null], + "arrow-ipc:hot": [118273, 122058, null, null, null], + "vortex-file-compressed:cold": [1092553, 1101477, null, null, null] } }, { @@ -111,11 +111,11 @@ "display_name": "taxi/uniform", "unit_kind": "time_ns", "series": { - "vortex-file-compressed:cold": [2916577, 2978837, null, null, null], - "parquet:cold": [39590379, 39465964, null, null, null], - "lance:cold": [8003975, 7960086, null, null, null], - "arrow-ipc:cold": [3097507, 3026104, null, null, null], - "vortex-file-compressed:hot": [818962, 829891, null, null, null] + "vortex-file-compressed:hot": [818962, 829891, null, null, null], + "parquet:hot": [39484266, 39349064, null, null, null], + "lance:hot": [6889605, 6999406, null, null, null], + "arrow-ipc:hot": [2940796, 2933221, null, null, null], + "vortex-file-compressed:cold": [2916577, 2978837, null, null, null] } } ] diff --git a/tests/unit/logo-banner.test.tsx b/tests/unit/logo-banner.test.tsx index 1ffcdbed..ca314752 100644 --- a/tests/unit/logo-banner.test.tsx +++ b/tests/unit/logo-banner.test.tsx @@ -8,16 +8,16 @@ import { LOGOS } from "@/components/logo-banner/logos"; // The logos Will cleared for public use, in the Home card's order: the // adopters and the projects that integrate Vortex. Spiral sits third, so it // is in view on load. Dash0 replaced Polar Signals, which it acquired. -// Apache Iceberg is tagged "Coming soon" until its Vortex support ships. +// Apache Iceberg is tagged "In proposal" until its Vortex support ships. const CLEARED = [ "Microsoft", "Palantir", "Spiral", "Firebolt", "Spice AI", - "LangChain", "DatologyAI", "Dash0", + "LangChain", "Milvus", "DuckDB", "Apache DataFusion", @@ -53,12 +53,12 @@ describe("LogoBanner", () => { ); }); - it("tags Apache Iceberg, and only Iceberg, as coming soon", () => { + it("tags Apache Iceberg, and only Iceberg, as in proposal", () => { const html = renderToStaticMarkup(); const first = html.split('