# Sep .NET CSV parsing: SIMD, parallel reads, and AOT deployment

> Sep is a C# library for reading and writing delimited text with an allocation-conscious, opinionated API. It fits performance-sensitive .NET workloads, especially machine learning pipelines, but its defaults differ from permissive CSV behavior.

**nietras/Sep** — World's Fastest .NET CSV Parser. Modern, minimal, fast, zero allocation, reading and writing of separated values (`csv`, `tsv` etc.). Cross-platform, trimmable and AOT/NativeAOT compatible with blazing fast SIMD vectorized parsing.

- Repository: https://github.com/nietras/Sep
- Website: http://nietras.com
- Stars: 1,479 · Forks: 55
- Language: C#
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/nietras-sep

## Why Sep targets a narrow .NET CSV workload

Sep addresses the cost of moving delimited text through a .NET application when throughput and allocation behavior matter. Its intended audience includes developers building data ingestion and machine learning systems, especially code that reads feature arrays, parses numeric columns, or writes transformed records back to delimited files. The package supports separated formats such as `csv` and `tsv`, rather than limiting itself to comma-separated input.

The design is explicitly opinionated. Sep does not automatically unescape or escape quotes, and it does not trim spaces by default. That choice matters because callers can predict how input becomes fields and output becomes text. The README describes the behavior as “What you read/write is what you get.” It also positions Sep as following the essentials of RFC 4180, with deliberate decisions around quoting and line endings rather than trying to absorb every variation encountered in real CSV files.

This is a useful fit for a controlled schema and a controlled producer. It is less suitable when a pipeline must silently repair ambiguous records or when teams expect a permissive parser to infer missing quoting and whitespace conventions. The API deliberately reduces configuration surface, which simplifies high-throughput paths but leaves more validation to the application.

## SepReader, SepWriter, and column parsing

The central flow is a reader created from text or a file. A reader can infer its separator from the header in the README example, expose a header index, and iterate rows. A row provides access to columns by name or index. Values can be read as `ReadOnlySpan<char>`, converted with `ToString()`, or parsed through types implementing `ISpanParsable<T>`.

The writer is derived from the reader specification with `reader.Spec.Writer()`. This means a caller can preserve the format context used to read the data while creating an output writer. Rows are created with `NewRow()`, values are assigned with `Set()` or `Format()`, and the row is written on disposal. The documentation also gives a multi-column path, such as parsing several columns into a span and formatting several values into one row operation.

The example below comes from the README. It shows the main read-transform-write shape, although the displayed section ends before the complete example is closed in the README.

## SIMD and parallel enumeration in Sep

Sep uses architecture-specific and cross-platform SIMD parsing paths. The README names 64-bit, 128-bit, 256-bit, and 512-bit paths, including AVX2, AVX-512 for .NET 8.0 and later, and NEON. Floating-point parsing uses `csFastFloat`, which the repository identifies as the implementation behind fast `float` and `double` parsing.

For workloads with enough independent work, Sep also exposes parallel enumeration. The README reports a comparison in which its parallel CSV parsing is up to 35x faster than CsvHelper for one floats-reader comparison. That figure is a project benchmark claim, not a guarantee for another application. Input shape, column types, hardware, parallelism, and the selected CsvHelper path can all affect the result.

The distinction between ordinary enumeration and parallel enumeration is practical rather than cosmetic. A sequential row loop is suitable when records must be processed in order or when downstream work is inherently serial. `ParallelEnumerate` is the API named in the documentation for parallel parsing. Engineers adopting Sep should inspect their actual bottleneck before changing concurrency, since parallel processing adds coordination behavior to a parser whose primary appeal is predictable, low-overhead data movement.

## Allocation, async, trimming, and NativeAOT constraints

Sep is built around `Span<T>`, `ArrayPool<T>`, `ref struct`, generic parsing and formatting, and other .NET 7-era language and runtime features. The README claims zero allocations after warmup for supported use cases, including reading or writing arrays of values without repeated allocations. That wording requires care. It describes supported scenarios after warmup, not every possible use of the API. Code that converts fields with `ToString()` may still create strings, and interpolated or application-owned output can introduce costs outside the library's optimized paths.

Async support uses `ValueTask`. The README states that it requires C# 13.0 or later, and that `SepReader` implements `IAsyncEnumerable<>` for .NET 9.0 and later. This places a real toolchain constraint on teams that want the asynchronous APIs.

Sep is also described as fully trimmable and compatible with Ahead-of-Time compilation, including NativeAOT. The stated reason is the absence of problematic reflection and dynamic code generation. That is relevant for command-line tools, services, and other deployments where startup footprint or native publish constraints matter. The repository includes publish and test scripts, but the README does not document a complete release or rollback procedure for consumers.

## The README's first Sep read and write flow

The code below is the README's opening example. The reader uses the inferred semicolon separator, while the writer reuses the reader specification. The row then demonstrates span access, named column lookup, typed parsing, and formatted output.

## Parsing defaults that create integration work

The most important limitation is behavioral rather than performance related. Automatic quote unescaping and quote escaping are disabled by default. Spaces are not trimmed by default either. Sep therefore requires callers to choose the corresponding reader or writer options when their data contract needs those transformations. A team migrating from a parser that accepts ragged quotes or removes whitespace may find that valid-looking files require explicit configuration or application-level normalization.

The README also calls its treatment of RFC 4180 pragmatic and opinionated. It does not claim that every RFC 4180 variant is accepted automatically. That distinction matters when files come from multiple external systems. Before adopting Sep, inspect the actual producer's quoting, embedded separator, line-ending, encoding, missing-field, and header conventions.

The API is compact, but compact APIs can shift work into application code. Validation of row widths, malformed records, type conversion failures, and semantic checks is not described as a substitute for an explicit ingestion policy. The documentation gives examples of parsing typed values, but it does not claim that every invalid input is automatically diagnosed or repaired.

## Sep versus CsvHelper for high-volume .NET parsing

CsvHelper is the named comparison in the repository. The README reports benchmark comparisons for reader and writer scenarios and specifically calls out a parallel floats-reader case in which Sep is up to 35x faster. The documented difference relevant to adoption is the execution model presented by Sep itself: SIMD-oriented parsing, low-allocation value access, parallel enumeration, and NativeAOT compatibility.

The repository does not provide enough benchmark methodology in the README to reproduce that claim, nor does the README describe CsvHelper's internal parsing design. For that reason, the comparison should remain a documented project claim rather than a universal ranking. Sep is more directly aimed at callers willing to work with spans, typed parsing, explicit formats, and lower-level control.

A practical evaluation should compare the same file, schema, row access pattern, output behavior, and exception policy. The difference in defaults can dominate the result before parser throughput is considered.

## Maintenance and upgrade implications for Sep

The repository is not archived, and its last push was on 2026-09-26. Releases include `v0.17.1` on 2026-09-19, `v0.17.0` on 2026-08-17, and `v0.16.0` on 2026-08-14. That release cadence indicates recent project activity, but it does not remove the need to review package changes before upgrading.

Sep is licensed under MIT. The repository contains `LICENSE`, `SECURITY.md`, `CONTRIBUTING.md`, tests, benchmark projects, and release-related scripts. The README does not describe a compatibility policy across all minor versions, nor does it document rollback steps for applications already published with a particular `Sep` version. The upgrade cost is therefore likely to include reviewing changed API behavior and validating native or trimmed deployment, but the exact migration burden cannot be inferred from the README alone.

## Conclusion

Sep is a practical fit for engineers processing large delimited datasets in .NET, particularly when parallel parsing, low allocation, trimming, or NativeAOT deployment matter. It is a weaker choice for applications that require automatic quote handling, trimming, or other forgiving behavior by default. Evaluate it first against a representative production file and verify the exact quoting, line-ending, allocation, and AOT requirements in your own build.

## FAQ

### How do I install Sep for a .NET project?

The repository links to the NuGet package named `Sep`, but the README does not include an installation command or package configuration snippet. Use the linked NuGet package documentation for the installation step and check the required .NET and C# versions before enabling async or AOT features.

### Does Sep automatically handle quotes and spaces in CSV files?

No. The README says that automatic escaping and unescaping of quotes and trimming of spaces are disabled by default. `SepReaderOptions` and `SepWriterOptions` provide the documented controls for enabling the relevant behavior.

### Is Sep suitable for NativeAOT and trimmed .NET applications?

Yes. The README states that Sep is trimmable and compatible with Ahead-of-Time compilation, including NativeAOT. It attributes that compatibility to the absence of problematic reflection and dynamic code generation, but the README does not provide a complete consumer publish tutorial.

## Sources

- [License: MIT](https://github.com/nietras/Sep/blob/main/LICENSE)
- [nietras/Sep on GitHub](https://github.com/nietras/Sep)
- [Project website](http://nietras.com)
- [README](https://github.com/nietras/Sep/blob/main/README.md)
- [Releases](https://github.com/nietras/Sep/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nietras-sep
