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
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
```

BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3775)
AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.203
[Host] : .NET 9.0.4 (9.0.425.16305), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
Job-DEDWQO : .NET 9.0.4 (9.0.425.16305), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI

Job=Job-DEDWQO EnvironmentVariables=DOTNET_GCDynamicAdaptationMode=0 Runtime=.NET 9.0
Toolchain=net90 InvocationCount=Default IterationTime=350ms
MaxIterationCount=15 MinIterationCount=5 WarmupCount=6
Quotes=False Reader=String

```
| Method | Parser | Scope | Rows | Mean | MB | MB/s | ns/row | Allocated |
|------- |--------------------------------------- |------ |------ |-----------:|---:|-------:|-------:|----------:|
| Sep_ | SepParserAvx2PackCmpOrMoveMaskTzcnt | Row | 50000 | 3.385 ms | 29 | 8619.9 | 67.7 | 1046 B |
| Sep_ | SepParserAvx512To256CmpOrMoveMaskTzcnt | Row | 50000 | 3.419 ms | 29 | 8535.4 | 68.4 | 1047 B |
| Sep_ | SepParserVector256NrwCmpExtMsbTzcnt | Row | 50000 | 3.424 ms | 29 | 8521.7 | 68.5 | 1078 B |
| Sep_ | SepParserSse2PackCmpOrMoveMaskTzcnt | Row | 50000 | 3.797 ms | 29 | 7685.3 | 75.9 | 968 B |
| Sep_ | SepParserAvx256To128CmpOrMoveMaskTzcnt | Row | 50000 | 3.815 ms | 29 | 7649.7 | 76.3 | 968 B |
| Sep_ | SepParserAvx512PackCmpOrMoveMaskTzcnt | Row | 50000 | 3.828 ms | 29 | 7623.3 | 76.6 | 1207 B |
| Sep_ | SepParserVector128NrwCmpExtMsbTzcnt | Row | 50000 | 3.852 ms | 29 | 7576.6 | 77.0 | 983 B |
| Sep_ | SepParserVector512NrwCmpExtMsbTzcnt | Row | 50000 | 4.201 ms | 29 | 6946.3 | 84.0 | 1273 B |
| Sep_ | SepParserIndexOfAny | Row | 50000 | 19.134 ms | 29 | 1525.1 | 382.7 | 1002 B |
| Sep_ | SepParserVector64NrwCmpExtMsbTzcnt | Row | 50000 | 143.313 ms | 29 | 203.6 | 2866.3 | 1656 B |
26 changes: 26 additions & 0 deletions benchmarks/AMD.Ryzen.9.9950X/PackageAssetsBench-Parsers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
```

BenchmarkDotNet v0.14.0, Windows 10 (10.0.19044.3086/21H2/November2021Update)
AMD Ryzen 9 9950X, 1 CPU, 32 logical and 16 physical cores
.NET SDK 9.0.203
[Host] : .NET 9.0.4 (9.0.425.16305), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
Job-HBFNQE : .NET 9.0.4 (9.0.425.16305), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI

Job=Job-HBFNQE EnvironmentVariables=DOTNET_GCDynamicAdaptationMode=0 Runtime=.NET 9.0
Toolchain=net90 InvocationCount=Default IterationTime=350ms
MaxIterationCount=15 MinIterationCount=5 WarmupCount=6
Quotes=False Reader=String

```
| Method | Parser | Scope | Rows | Mean | MB | MB/s | ns/row | Allocated |
|------- |--------------------------------------- |------ |------ |----------:|---:|--------:|-------:|----------:|
| Sep_ | SepParserAvx512To256CmpOrMoveMaskTzcnt | Row | 50000 | 1.351 ms | 29 | 21597.7 | 27.0 | 1038 B |
| Sep_ | SepParserVector256NrwCmpExtMsbTzcnt | Row | 50000 | 1.416 ms | 29 | 20608.5 | 28.3 | 1070 B |
| Sep_ | SepParserAvx2PackCmpOrMoveMaskTzcnt | Row | 50000 | 1.417 ms | 29 | 20599.3 | 28.3 | 1038 B |
| Sep_ | SepParserAvx512PackCmpOrMoveMaskTzcnt | Row | 50000 | 1.463 ms | 29 | 19944.3 | 29.3 | 1198 B |
| Sep_ | SepParserAvx256To128CmpOrMoveMaskTzcnt | Row | 50000 | 1.499 ms | 29 | 19465.5 | 30.0 | 958 B |
| Sep_ | SepParserSse2PackCmpOrMoveMaskTzcnt | Row | 50000 | 1.511 ms | 29 | 19312.5 | 30.2 | 958 B |
| Sep_ | SepParserVector128NrwCmpExtMsbTzcnt | Row | 50000 | 1.599 ms | 29 | 18252.1 | 32.0 | 975 B |
| Sep_ | SepParserVector512NrwCmpExtMsbTzcnt | Row | 50000 | 1.615 ms | 29 | 18067.4 | 32.3 | 1262 B |
| Sep_ | SepParserIndexOfAny | Row | 50000 | 10.471 ms | 29 | 2787.0 | 209.4 | 972 B |
| Sep_ | SepParserVector64NrwCmpExtMsbTzcnt | Row | 50000 | 63.446 ms | 29 | 459.9 | 1268.9 | 1280 B |
32 changes: 32 additions & 0 deletions src/Sep.ComparisonBenchmarks/PackageAssetsBench.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Order;
using CsvHelper;
using CsvHelper.Configuration;
using Sylvan.Data.Csv;
Expand Down Expand Up @@ -542,3 +543,34 @@ public class GcServerLongAssetPackageAssetsBench : LongAssetPackageAssetsBench
[GcServer(true)]
public class GcServerLongQuotesAssetPackageAssetsBench : LongQuotesAssetPackageAssetsBench
{ }

[BenchmarkCategory("0_Parsers")]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
public class ParsersRowPackageAssetsBench : PackageAssetsBench
{
const int DefaultLineCount = 50_000;

public ParsersRowPackageAssetsBench() : this(false) { }
public ParsersRowPackageAssetsBench(bool quoteAroundSomeCols) : base("Row", DefaultLineCount, quoteAroundSomeCols) { }

[ParamsSource(nameof(ParserParams))] // Attributes for params is challenging 👇
public string Parser { get; set; } = SepParserFactory.GetForceParserName();
public IEnumerable<string> ParserParams() => SepParserFactory.AvailableFactories.Keys;

[GlobalSetup]
public void GlobalSetup()
{
Environment.SetEnvironmentVariable(SepParserFactory.SepForceParserEnvName, Parser);
var name = SepParserFactory.GetForceParserName();
Console.WriteLine($"// Using parser: {name}");
}

[Benchmark]
public void Sep_()
{
using var reader = Sep.Reader(o => o with { HasHeader = false })
.From(Reader.CreateReader());
foreach (var row in reader) { }
}
}
1 change: 1 addition & 0 deletions src/Sep.ComparisonBenchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
{ nameof(PackageAssetsBench) + "Quotes", new[] { typeof(QuotesRowPackageAssetsBench), typeof(QuotesColsPackageAssetsBench), typeof(QuotesAssetPackageAssetsBench), typeof(LongQuotesAssetPackageAssetsBench), } },
{ nameof(PackageAssetsBench) + "SpacesQuotes", new[] { typeof(SpacesQuotesColsPackageAssetsBench) } },
{ nameof(FloatsReaderBench), new[] { typeof(RowFloatsReaderBench), typeof(ColsFloatsReaderBench), typeof(FloatsFloatsReaderBench), } },
{ nameof(PackageAssetsBench) + "-Parsers", new[] { typeof(ParsersRowPackageAssetsBench), } },
};
foreach (var (name, benchTypes) in nameToBenchTypesSet)
{
Expand Down
10 changes: 4 additions & 6 deletions src/Sep/Internals/SepParserFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ namespace nietras.SeparatedValues;

static class SepParserFactory
{
const string SepForceParserEnvName = "SEPFORCEPARSER";
internal const string SepForceParserEnvName = "SEPFORCEPARSER";

static SepParserFactory()
{
CreateBest = CreateBestFunc();
}
static Func<SepParserOptions, ISepParser>? _createBest = null;

[ExcludeFromCodeCoverage]
internal static Func<SepParserOptions, ISepParser> CreateBest { get; }
internal static Func<SepParserOptions, ISepParser> CreateBest =>
_createBest ??= CreateBestFunc();

[ExcludeFromCodeCoverage]
internal static Func<SepParserOptions, ISepParser> CreateBestFunc()
Expand Down