Parquet.SourceGenerator.Attributes
0.0.3
dotnet add package Parquet.SourceGenerator.Attributes --version 0.0.3
NuGet\Install-Package Parquet.SourceGenerator.Attributes -Version 0.0.3
<PackageReference Include="Parquet.SourceGenerator.Attributes" Version="0.0.3" />
<PackageVersion Include="Parquet.SourceGenerator.Attributes" Version="0.0.3" />
<PackageReference Include="Parquet.SourceGenerator.Attributes" />
paket add Parquet.SourceGenerator.Attributes --version 0.0.3
#r "nuget: Parquet.SourceGenerator.Attributes, 0.0.3"
#:package Parquet.SourceGenerator.Attributes@0.0.3
#addin nuget:?package=Parquet.SourceGenerator.Attributes&version=0.0.3
#tool nuget:?package=Parquet.SourceGenerator.Attributes&version=0.0.3
Parquet.SourceGenerator
A zero-reflection C# Roslyn source generator that emits Parquet serializers and deserializers at compile time, targeting Parquet.Net low-level primitives.
📦 Installation
dotnet add package Parquet.SourceGenerator
dotnet add package Parquet.Net
Parquet.SourceGenerator.Attributes is automatically included as a dependency. Parquet.Net must be referenced directly by your project.
📖 Quick Start Example
using System;
using Parquet.SourceGenerator;
[ParquetSerializable]
public partial record UserEvent
{
[ParquetColumn("event_id", Order = 1)]
public Guid Id { get; init; }
[ParquetColumn("username", Order = 2)]
public string Username { get; init; } = string.Empty;
[ParquetColumn("timestamp", Order = 3)]
[ParquetTimestamp(ParquetTimestampUnit.Microseconds)]
public DateTime Timestamp { get; init; }
[ParquetColumn("duration", Order = 4)]
public TimeSpan Duration { get; init; }
}
Writing Parquet Files
List<UserEvent> events = GetEvents();
using var stream = File.Create("events.parquet");
// Simple write
await events.WriteParquetAsync(stream);
// Chunked row-group streaming write
await events.WriteParquetBatchedAsync(stream, rowGroupSize: 10_000);
// Stream directly from IAsyncEnumerable<T>
IAsyncEnumerable<UserEvent> eventStream = GetAsyncEventStream();
await eventStream.WriteParquetAsync(stream, rowGroupSize: 10_000);
Reading Parquet Files (Sequential & Parallel)
using var stream = File.OpenRead("events.parquet");
// Sequential read
List<UserEvent> events = await UserEventParquetExtensions.ReadParquetAsync(stream);
// Multi-core parallel read across row groups
List<UserEvent> parallelEvents = await UserEventParquetExtensions.ReadParquetParallelAsync(stream, maxDegreeOfParallelism: 4);
// Read from in-memory byte buffer
ReadOnlyMemory<byte> buffer = File.ReadAllBytes("events.parquet");
List<UserEvent> memEvents = await UserEventParquetExtensions.ReadParquetAsync(buffer);
Custom Configuration (ParquetSerializerOptions)
var options = new ParquetSerializerOptions
{
RowGroupSize = 25_000,
MaxDegreeOfParallelism = 8,
CompressionMethod = ParquetCompressionMethod.Zstd
};
await events.WriteParquetBatchedAsync(stream, options: options);
Compression options: None, Snappy (default), Gzip, Lz4, Brotli, Zstd.
⚡ Performance & Benchmarks
Zero-reflection C# source generation vs ParquetSerializer v6 reflection baseline:
| Operation | Scale | Reflection Baseline | Source Generator | Speedup | Memory Reduction |
|---|---|---|---|---|---|
| File Serialization (Write) | 100,000 items | 7.05 ms (11.00 MB) | 2.91 ms (5.74 MB) | ⚡ 2.4x faster | 📉 48% less memory |
| Streaming Batched Write | 100,000 items | 7.05 ms (11.00 MB) | 3.50 ms (5.03 MB) | ⚡ 2.0x faster | 📉 54% less memory |
| File Deserialization (Read) | 100,000 items | 9.81 ms (12.30 MB) | 5.57 ms (8.99 MB) | ⚡ 1.8x faster | 📉 27% less memory |
| Parallel Deserialization (Read) | 100,000 items | 9.81 ms (12.30 MB) | 5.68 ms (9.86 MB) | ⚡ 1.7x faster | 📉 20% less memory |
| Streaming Read (IAsyncEnumerable) | 100,000 items | 9.81 ms (12.30 MB) | 4.13 ms (8.22 MB) | ⚡ 2.4x faster | 📉 33% less memory |
| Guid Serialization | 100,000 items | 8.97 ms (17.70 MB) | 6.82 ms (10.70 MB) | ⚡ 1.3x faster | 📉 40% less memory |
📌 Note: BenchmarkDotNet results captured on GitHub Actions. Detailed multi-scale reports (1K, 10K, 100K, 1M rows) are in docs/BENCHMARKS.md.
🌐 Real-World Provenanced Dataset Benchmarks
Fixed public datasets tracked under Git LFS with full cryptographic SHA-256 data provenance:
- TPC-H SF 0.01 LineItem: 60,175 rows, 16 columns (decimals, dates, strings, dictionary encoding)
- Adult Census Income: 32,561 rows, 15 columns (9 categorical dictionary columns)
- Diamonds: 53,940 rows, 10 columns (continuous float metrics & ordinal cuts)
| Operation | Scale | Reflection Baseline | Source Generator | Speedup | Memory Reduction |
|---|---|---|---|---|---|
| TPC-H LineItem Deserialization | 60,175 rows | 85.46 ms (55.11 MB) | 55.29 ms (38.59 MB) | ⚡ 1.5x faster | 📉 30% less memory |
| TPC-H LineItem Parallel Deserialization | 60,175 rows | 85.46 ms (55.11 MB) | 58.27 ms (39.07 MB) | ⚡ 1.4x faster | 📉 29% less memory |
| TPC-H LineItem Streaming Deserialization | 60,175 rows | 85.46 ms (55.11 MB) | 44.44 ms (38.13 MB) | ⚡ 1.9x faster | 📉 31% less memory |
| Adult Census Deserialization (Dictionaries) | 32,561 rows | 37.94 ms (29.25 MB) | 28.74 ms (20.24 MB) | ⚡ 1.3x faster | 📉 31% less memory |
| Adult Census Parallel Deserialization | 32,561 rows | 37.94 ms (29.25 MB) | 30.07 ms (22.90 MB) | ⚡ 1.3x faster | 📉 22% less memory |
| Adult Census Streaming Deserialization | 32,561 rows | 37.94 ms (29.25 MB) | 11.49 ms (19.99 MB) | ⚡ 3.3x faster | 📉 32% less memory |
| Diamonds Deserialization | 53,940 rows | 22.09 ms (19.78 MB) | 11.92 ms (12.52 MB) | ⚡ 1.9x faster | 📉 37% less memory |
| Diamonds Parallel Deserialization | 53,940 rows | 22.09 ms (19.78 MB) | 13.63 ms (15.65 MB) | ⚡ 1.6x faster | 📉 21% less memory |
| Diamonds Streaming Deserialization | 53,940 rows | 22.09 ms (19.78 MB) | 7.52 ms (12.11 MB) | ⚡ 2.9x faster | 📉 39% less memory |
🗜️ TPC-H LineItem Multi-Codec Serialization Throughput (60,175 rows)
| Codec | Compression Profile | Serialization Time | Allocated Memory |
|---|---|---|---|
| Snappy | Generator Built-in | 37.85 ms | 14.89 MB |
| Zstandard (Fastest) | Generator Built-in | 48.32 ms | 22.40 MB |
| Zstandard (Optimal) | Generator Built-in | 49.94 ms | 23.06 MB |
| Uncompressed | Generator Built-in | 30.77 ms | 38.18 MB |
🛡️ Compiler Diagnostics
| Diagnostic ID | Severity | Description |
|---|---|---|
PARQ001 |
Error | Target type decorated with [ParquetSerializable] must be declared as partial. |
PARQ002 |
Error | Duplicate [ParquetColumn] column names detected on model. |
PARQ003 |
Warning | Target type has no valid public serializable properties or fields. |
PARQ004 |
Warning | Non-public property decorated with [ParquetColumn] will be ignored. |
PARQ005 |
Error | Invalid [ParquetDecimal] precision or scale parameters. |
🚀 Native AOT & Cold-Start Performance
Under Native AOT, cold invocations (CLI tools, serverless Lambda functions, batch workers) run 7.2× faster with 72% less memory:
| Metric | CoreCLR (JIT) | Native AOT | Improvement |
|---|---|---|---|
| Total Process Time | 358 ms | 50 ms | ⚡ 7.2× faster |
| CPU User Time | 0.30 s | 0.02 s | ⚡ 15× less CPU |
| Peak Working Set | 57.0 MB | 15.8 MB | 📉 72% less RAM |
To enable Native AOT:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
🔗 Links & Resources
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Memory (>= 4.6.3)
-
.NETStandard 2.1
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Parquet.SourceGenerator.Attributes:
| Package | Downloads |
|---|---|
|
Parquet.SourceGenerator
Package Description |
|
|
Parquet.SourceGenerator.Legacy
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.3 | 160 | 9/5/2026 |
| 0.0.2 | 159 | 9/2/2026 |
| 0.0.1-dev.2 | 82 | 8/6/2026 |
| 0.0.1-dev.1 | 71 | 8/5/2026 |