Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.0
version: 0.16.0

- name: Install dependencies
run: bun install
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.0
version: 0.16.0

- name: Build native library
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.0
version: 0.16.0

- name: Build native library
run: |
Expand Down Expand Up @@ -95,7 +95,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.0
version: 0.16.0

- name: Download all artifacts
uses: actions/download-artifact@v4
Expand Down
32 changes: 16 additions & 16 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@ pub fn build(b: *std.Build) void {

// Unit tests (native only)
if (!is_wasm) {
const unit_tests_module = b.createModule(.{
.root_source_file = b.path("src/zig/parser.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
const unit_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("src/zig/parser.zig"),
.target = target,
.optimize = optimize,
}),
.root_module = unit_tests_module,
});
unit_tests.linkLibC();

// Link iconv library - only needed on macOS when building natively
// On Linux glibc, iconv is built into libc
const is_native_macos = target.result.os.tag == .macos and target.query.isNative();
if (is_native_macos) {
unit_tests.linkSystemLibrary("iconv");
unit_tests_module.linkSystemLibrary("iconv", .{});
}

const run_unit_tests = b.addRunArtifact(unit_tests);
Expand All @@ -42,24 +43,23 @@ pub fn build(b: *std.Build) void {

/// Build native shared library
fn buildNative(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) void {
const lib_module = b.createModule(.{
.root_source_file = b.path("src/zig/parser.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
const lib = b.addLibrary(.{
.name = "turbocsv",
.root_module = b.createModule(.{
.root_source_file = b.path("src/zig/parser.zig"),
.target = target,
.optimize = optimize,
}),
.root_module = lib_module,
.linkage = .dynamic,
});

// Link libc for basic C support
lib.linkLibC();

// Link iconv library on macOS (required for character encoding support)
// On Linux (glibc), iconv is built into libc
const target_os = target.result.os.tag;
if (target_os == .macos) {
lib.linkSystemLibrary("iconv");
lib_module.linkSystemLibrary("iconv", .{});
}

// Install the library
Expand Down
2 changes: 1 addition & 1 deletion landing/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function App() {
<Router
root={(props) => (
<MetaProvider>
<Title>TurboCSV - High-performance CSV parser with SIMD acceleration</Title>
<Title>TurboCSV - Fast CSV parsing with Zig, SIMD, and Fast Mode</Title>
<Link rel="preconnect" href="https://fonts.googleapis.com" />
<Link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" />
<Link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&display=swap" rel="stylesheet" />
Expand Down
42 changes: 22 additions & 20 deletions landing/src/components/BenchmarkChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default function BenchmarkChart() {
<div class="container">
<h2>Performance Comparison</h2>
<p class="benchmark-subtitle">
Parsing 100K rows (10 MB) on Apple M1 Pro. Higher is better.
End-to-end benchmark including file reads on Apple Silicon. Clean generated CSV data. Higher is better.
</p>

<div class="benchmark-table">
Expand All @@ -17,44 +17,46 @@ export default function BenchmarkChart() {
<th>1K rows</th>
<th>10K rows</th>
<th>100K rows</th>
<th>100K (wide)</th>
</tr>
</thead>
<tbody>
<tr class="highlight">
<td>TurboCSV</td>
<td>122.6 MB/s</td>
<td>165.3 MB/s</td>
<td>176.1 MB/s</td>
<td>269.3 MB/s</td>
<td>TurboCSV Fast Mode</td>
<td>116.5 MB/s</td>
<td>177.4 MB/s</td>
<td>172.4 MB/s</td>
</tr>
<tr>
<td>PapaParse</td>
<td>84.0 MB/s</td>
<td>109.3 MB/s</td>
<td>112.0 MB/s</td>
<td>224.6 MB/s</td>
<td>65.8 MB/s</td>
<td>98.7 MB/s</td>
<td>111.5 MB/s</td>
</tr>
<tr>
<td>TurboCSV Native</td>
<td>42.5 MB/s</td>
<td>53.0 MB/s</td>
<td>57.6 MB/s</td>
</tr>
<tr>
<td>csv-parse</td>
<td>25.2 MB/s</td>
<td>34.9 MB/s</td>
<td>35.3 MB/s</td>
<td>40.3 MB/s</td>
<td>25.1 MB/s</td>
<td>35.1 MB/s</td>
<td>33.3 MB/s</td>
</tr>
<tr>
<td>fast-csv</td>
<td>24.8 MB/s</td>
<td>28.7 MB/s</td>
<td>30.2 MB/s</td>
<td>38.1 MB/s</td>
<td>22.7 MB/s</td>
<td>33.5 MB/s</td>
<td>32.6 MB/s</td>
</tr>
</tbody>
</table>
</div>

<p class="benchmark-note">
Run the benchmark yourself: <code>bun run benchmark:compare</code>
Fast Mode is optimized for simple CSV without quoted delimiters or multi-line fields. Run it yourself:
{" "}<code>bun run benchmark:compare</code>
</p>
</div>
</section>
Expand Down
7 changes: 7 additions & 0 deletions landing/src/components/CodeExample.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
margin-bottom: 1rem;
border-bottom: 1px solid var(--border-color);
padding-bottom: 0.5rem;
max-width: 100%;
overflow-x: auto;
scrollbar-width: thin;
}

.tab {
Expand All @@ -22,6 +25,7 @@
cursor: pointer;
border-radius: 4px;
transition: all 0.2s ease;
flex: 0 0 auto;
}

.tab:hover {
Expand All @@ -38,13 +42,15 @@
position: relative;
min-height: 350px;
margin-bottom: 1.5rem;
min-width: 0;
}

.code-block {
position: absolute;
top: 0;
left: 0;
right: 0;
min-width: 0;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease;
Expand All @@ -66,6 +72,7 @@
padding: 1.5rem;
border-radius: 8px;
overflow-x: auto;
max-width: 100%;
font-size: 0.875rem;
line-height: 1.6;
background: #1d1f21 !important;
Expand Down
6 changes: 5 additions & 1 deletion landing/src/components/CodeExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,18 @@ parser.close();`,
},
{
id: "cli",
label: "CLI (v0.3.0)",
label: "CLI & Benchmarks",
lang: "bash",
code: `# Trim whitespace and skip bad rows
turbocsv head --trim --skip-errors data.csv

# Fast mode with dynamic typing
turbocsv head --fast --dynamic-typing --format json data.csv

# Run local benchmarks
bun run benchmark
bun run benchmark:compare

# Validate with structured error reporting
turbocsv validate data.csv
# Output: ERROR [TooFewFields] at row 42: Expected 5 fields, got 3
Expand Down
12 changes: 6 additions & 6 deletions landing/src/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function Hero() {
</p>

<p class="subtitle">
Built with Zig for native performance. Now with Fast Mode, security hardening, and 22 CLI flags.
Built with Zig for native performance. Fast Mode now leads the benchmark suite for clean CSV data.
</p>

<div class="install-box">
Expand All @@ -54,17 +54,17 @@ export default function Hero() {

<div class="stats">
<div class="stat">
<span class="stat-value">269 MB/s</span>
<span class="stat-label">Peak throughput</span>
<span class="stat-value">177 MB/s</span>
<span class="stat-label">Fast Mode throughput</span>
</div>
<div class="stat-divider"></div>
<div class="stat">
<span class="stat-value">5.8x</span>
<span class="stat-label">faster than fast-csv</span>
<span class="stat-value">1.79x</span>
<span class="stat-label">faster than PapaParse</span>
</div>
<div class="stat-divider"></div>
<div class="stat">
<span class="stat-value">6.35x</span>
<span class="stat-value">6.32x</span>
<span class="stat-label">faster than csv-parse</span>
</div>
</div>
Expand Down
16 changes: 16 additions & 0 deletions landing/src/components/WhatsNew.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@
gap: 1.25rem;
}

.current-grid {
margin-bottom: 2.5rem;
}

@media (min-width: 640px) {
.whats-new-grid {
grid-template-columns: repeat(2, 1fr);
}

.current-grid {
grid-template-columns: repeat(3, 1fr);
}
}

.whats-new-card {
Expand All @@ -36,6 +44,10 @@
border-color: var(--ds-gray-500);
}

.current-card {
border-color: var(--ds-gray-500);
}

.whats-new-card h3 {
font-size: 1rem;
margin-bottom: 0.75rem;
Expand Down Expand Up @@ -116,6 +128,10 @@
color: var(--text-secondary);
}

.release-title {
margin-top: 0;
}

@keyframes fadeIn {
from {
opacity: 0;
Expand Down
54 changes: 52 additions & 2 deletions landing/src/components/WhatsNew.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
import { For, createSignal } from "solid-js";
import "./WhatsNew.css";

const currentFeatures = [
{
title: "Benchmark Clarity",
features: [
<><code>bun run benchmark</code> restored with generated sample files</>,
<><code>benchmark:compare</code> now reports native and Fast Mode separately</>,
"Benchmarks now time file reads for JavaScript parsers too",
"Fast Mode leads the simple CSV benchmark suite",
],
},
{
title: "Zig 0.16 Ready",
features: [
"Build script migrated to current module-level linking APIs",
<><code>std.Io</code> file APIs replace deprecated filesystem calls</>,
<><code>DebugAllocator</code> replaces the old general-purpose allocator</>,
<><code>ArrayList</code> usage updated for allocator-explicit methods</>,
],
},
{
title: "Runtime Polish",
features: [
"Row metadata now reuses parser header arrays instead of copying per row",
"Parallel parser synchronization updated for Zig 0.16",
"Focused unit tests can generate fixtures in clean checkouts",
"Native build and Zig test suite pass on the current toolchain",
],
},
];

const v3Features = [
{
title: "Security & Validation",
Expand Down Expand Up @@ -71,9 +101,29 @@ export default function WhatsNew() {
return (
<section class="whats-new" id="whats-new">
<div class="container">
<h2>What's New in v0.3.0</h2>
<h2>What's New in v0.3.4</h2>
<p class="whats-new-subtitle">
Current toolchain support, clearer benchmarks, and Fast Mode performance visibility.
</p>

<div class="whats-new-grid current-grid">
<For each={currentFeatures}>
{(group) => (
<div class="whats-new-card current-card">
<h3>{group.title}</h3>
<ul class="whats-new-list">
<For each={group.features}>
{(feature) => <li>{feature}</li>}
</For>
</ul>
</div>
)}
</For>
</div>

<h3 class="v2-title release-title">Previously in v0.3.0</h3>
<p class="whats-new-subtitle">
Major feature release — 22 new CLI flags, security hardening, Fast Mode, and robust error handling.
Major feature release — 22 CLI flags, security hardening, Fast Mode, and robust error handling.
</p>

<div class="whats-new-grid">
Expand Down
Loading
Loading