Skip to content

Commit 1b22df0

Browse files
committed
Added benhcmarks, edited readme
1 parent b6e9c08 commit 1b22df0

File tree

4 files changed

+141
-9
lines changed

4 files changed

+141
-9
lines changed

CsvExport.sln

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ VisualStudioVersion = 17.5.33502.453
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CsvExport", "CsvExport\CsvExport.csproj", "{DF3D41B8-E1F7-4CF2-8AC3-E5FA3BB75EA0}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{02924EC2-EB46-4B01-8E49-D19B0FACD084}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "UnitTests\UnitTests.csproj", "{02924EC2-EB46-4B01-8E49-D19B0FACD084}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpeedBenchmarks", "SpeedBenchmarks\SpeedBenchmarks.csproj", "{4F2C2C15-CB31-4B12-8E8D-57591EE218A5}"
911
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
2123
{02924EC2-EB46-4B01-8E49-D19B0FACD084}.Debug|Any CPU.Build.0 = Debug|Any CPU
2224
{02924EC2-EB46-4B01-8E49-D19B0FACD084}.Release|Any CPU.ActiveCfg = Release|Any CPU
2325
{02924EC2-EB46-4B01-8E49-D19B0FACD084}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{4F2C2C15-CB31-4B12-8E8D-57591EE218A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{4F2C2C15-CB31-4B12-8E8D-57591EE218A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{4F2C2C15-CB31-4B12-8E8D-57591EE218A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{4F2C2C15-CB31-4B12-8E8D-57591EE218A5}.Release|Any CPU.Build.0 = Release|Any CPU
2430
EndGlobalSection
2531
GlobalSection(SolutionProperties) = preSolution
2632
HideSolutionNode = FALSE

README.md

+42-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# CsvExport
2-
A very simple CSV-export tool for C#, code ispired by a thread at Stackoverflow, (C) Chris Hulbert
3-
4-
This was previously published as a "Gist" but I moved it here, for easier forking/contributing.
2+
A very simple and fast CSV-export tool for C#.
53

64
[![.NET](https://github.com/jitbit/CsvExport/actions/workflows/dotnet.yml/badge.svg)](https://github.com/jitbit/CsvExport/actions/workflows/dotnet.yml)
75

@@ -12,17 +10,24 @@ This was previously published as a "Gist" but I moved it here, for easier forkin
1210
3. Exports dates in timezone-proof format
1311
4. Extremely easy to use
1412
5. NET Standard 2.0 library (compatible with both .NET Core and .NET Framework)
13+
6. 30 times faster than CsvHelper
14+
7. 4-times less memory usage
1515

1616
## Benchmarks
1717

18-
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
19-
|---------- |------------:|----------:|---------:|--------:|-------:|----------:|
20-
| CsvHelper | 1,311.23 us | 16.935 us | 0.928 us | 15.6250 | 7.8125 | 107.42 KB |
21-
| CsvExport (this library) | 32.24 us | 1.365 us | 0.075 us | 4.7607 | 0.2441 | 29.37 KB |
18+
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
19+
|------------------ |------------:|----------:|---------:|--------:|-------:|----------:|
20+
| CsvHelper | 1,300.38 us | 32.043 us | 1.756 us | 17.5781 | 7.8125 | 114.25 KB |
21+
| CsvExport_Manual | 31.22 us | 5.750 us | 0.315 us | 4.7607 | 0.2441 | 29.37 KB |
22+
| CsvExport_Typed | 52.68 us | 1.453 us | 0.080 us | 4.7607 | 0.1221 | 29.46 KB |
23+
24+
This benchmark is generating a 100-line CSV file with 4 columns. Check the "SpeedBenchmarks" code.
2225

2326
## Usage example:
2427

25-
Install via Nuget `Install-Package CsvExport` then:
28+
Install via Nuget `Install-Package CsvExport`
29+
30+
For "manual" CSV generation use this:
2631

2732
```c#
2833
var myExport = new CsvExport();
@@ -41,6 +46,35 @@ myExport["Date Opened"] = new DateTime(2005, 1, 1, 9, 30, 0);
4146
return File(myExport.ExportToBytes(), "text/csv", "results.csv");
4247
```
4348

49+
For generating CSV out of a typed `List<T>` of objects:
50+
51+
```c#
52+
53+
public class Foo
54+
{
55+
public string Region { get; set; }
56+
public int Sales { get; set; }
57+
public DateTime DateOpened { get; set; }
58+
}
59+
60+
var list = new List<Foo>
61+
{
62+
new Foo { Region = "Los Angeles", Sales = 123321, DateOpened = DateTime.Now },
63+
new Foo { Region = "Canberra in Australia", Sales = 123321, DateOpened = DateTime.Now },
64+
};
65+
66+
var myExport = new CsvExport();
67+
myExport.AddRows(list);
68+
string csv = myExport.Export();
69+
```
70+
Configuring is done via constructor parameters:
71+
72+
```
73+
var myExport = new CsvExport(columnSeparator: ",", includeColumnSeparatorDefinitionPreamble: true, includeHeaderRow: true);
74+
```
75+
76+
Also, methods `ExportToFile` and `ExportToBytes` offer an optional encoding parameter.
77+
4478
### License
4579

4680
The code is licensed under *MIT License*.

SpeedBenchmarks/Program.cs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using BenchmarkDotNet.Attributes;
2+
using BenchmarkDotNet.Running;
3+
using Csv;
4+
using CsvHelper;
5+
using Microsoft.Extensions.Logging;
6+
7+
BenchmarkRunner.Run<SpeedBenchmarks.BenchMark>();
8+
9+
namespace SpeedBenchmarks
10+
{
11+
[ShortRunJob, MemoryDiagnoser]
12+
public class BenchMark
13+
{
14+
private static List<MyClass> _myClasses = new List<MyClass>();
15+
16+
[GlobalSetup]
17+
public void Setup()
18+
{
19+
for (int i = 0; i < 100; i++)
20+
{
21+
_myClasses.Add(new MyClass { Col1 = "test1", Col2 = "test2", Col3 = "test3", Col4 = "test4" });
22+
}
23+
}
24+
25+
[Benchmark]
26+
public void CsvHelper()
27+
{
28+
using (var stream = new MemoryStream())
29+
using (var reader = new StreamReader(stream))
30+
using (var writer = new StreamWriter(stream))
31+
using (var csv = new CsvWriter(writer, System.Globalization.CultureInfo.InvariantCulture))
32+
{
33+
csv.WriteRecords(_myClasses);
34+
writer.Flush();
35+
stream.Position = 0;
36+
var text = reader.ReadToEnd();
37+
}
38+
}
39+
40+
[Benchmark]
41+
public void CsvExport_Manual()
42+
{
43+
var c = new CsvExport();
44+
for (int i = 0; i < 100; i++)
45+
{
46+
c.AddRow();
47+
c["Col1"] = "test1";
48+
c["Col2"] = "test2";
49+
c["Col3"] = "test3";
50+
c["Col4"] = "test4";
51+
}
52+
53+
var r = c.Export();
54+
}
55+
56+
[Benchmark]
57+
public void CsvExport_GenericType()
58+
{
59+
var c = new CsvExport();
60+
c.AddRows(_myClasses);
61+
62+
var r = c.Export();
63+
}
64+
}
65+
66+
public class MyClass
67+
{
68+
public string Col1 { get; set; }
69+
public string Col2 { get; set; }
70+
public string Col3 { get; set; }
71+
public string Col4 { get; set; }
72+
}
73+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
12+
<PackageReference Include="CsvHelper" Version="30.0.1" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\CsvExport\CsvExport.csproj" />
17+
</ItemGroup>
18+
19+
</Project>

0 commit comments

Comments
 (0)