Skip to content

Commit fa51ef4

Browse files
Benchmarks refactoring and adaptation for making them run on Github Actions (#777)
* Code cleanup - Added InternalsVisiblesTo attribute to make tests work without workarounds in the source - Added test generated excel file to gitignore - Refactored new MiniExcelPictureImplement class * Benchmark refactoring to make them run in github actions
1 parent 2f0f977 commit fa51ef4

22 files changed

+420
-401
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,4 @@ FodyWeavers.xsd
402402
/tests/MiniExcel.Tests.AspNetMvc/packages
403403
/TestTemplate
404404
/tests/MiniExcelTests/TemplateOptimization
405+
/samples/xlsx/Test_EnableWriteFilePath.xlsx

MiniExcel.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniExcelTests", "tests\Min
3333
EndProject
3434
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{77A8A169-168B-457F-AB5F-48F30D6BB33C}"
3535
EndProject
36+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniExcel.Benchmarks", "benchmarks\MiniExcel.Benchmarks\MiniExcel.Benchmarks.csproj", "{F1BDF4D7-F3C4-4114-82F6-EF81567DFBD8}"
37+
EndProject
3638
Global
3739
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3840
Debug|Any CPU = Debug|Any CPU
@@ -47,13 +49,18 @@ Global
4749
{77F2C86B-0F17-4370-AB38-A089F9DF4ED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
4850
{77F2C86B-0F17-4370-AB38-A089F9DF4ED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
4951
{77F2C86B-0F17-4370-AB38-A089F9DF4ED5}.Release|Any CPU.Build.0 = Release|Any CPU
52+
{F1BDF4D7-F3C4-4114-82F6-EF81567DFBD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53+
{F1BDF4D7-F3C4-4114-82F6-EF81567DFBD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
54+
{F1BDF4D7-F3C4-4114-82F6-EF81567DFBD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
55+
{F1BDF4D7-F3C4-4114-82F6-EF81567DFBD8}.Release|Any CPU.Build.0 = Release|Any CPU
5056
EndGlobalSection
5157
GlobalSection(SolutionProperties) = preSolution
5258
HideSolutionNode = FALSE
5359
EndGlobalSection
5460
GlobalSection(NestedProjects) = preSolution
5561
{097903C9-1F81-4427-B4C8-530CB59687B8} = {CC1E0601-AEC9-42D7-8F6A-3FB3939EED16}
5662
{77F2C86B-0F17-4370-AB38-A089F9DF4ED5} = {359A7094-3353-48F2-B3E1-FE9E59698318}
63+
{F1BDF4D7-F3C4-4114-82F6-EF81567DFBD8} = {77A8A169-168B-457F-AB5F-48F30D6BB33C}
5764
EndGlobalSection
5865
GlobalSection(ExtensibilityGlobals) = postSolution
5966
SolutionGuid = {51DF25DA-2DCB-4883-90FE-399DA950D4F2}

benchmarks/MiniExcel.Benchmarks/BenchmarkBase.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22

33
public abstract class BenchmarkBase
44
{
5-
//public const string filePath = @"Test10x10.xlsx";
6-
//public const int rowCount = 1_0;
5+
public const string FilePath = "Test1,000,000x10.xlsx";
6+
public const int RowCount = 1_000_000;
77

8-
public const string filePath = "Test1,000,000x10.xlsx";
9-
public const int rowCount = 1_000_000;
10-
11-
public IEnumerable<DemoDto> GetValue() => Enumerable.Range(1, rowCount).Select(s => new DemoDto());
8+
public IEnumerable<DemoDto> GetValue() => Enumerable.Range(1, RowCount).Select(s => new DemoDto());
129

1310
public class DemoDto
1411
{
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System.Text;
2+
using BenchmarkDotNet.Attributes;
3+
using ClosedXML.Excel;
4+
using DocumentFormat.OpenXml;
5+
using DocumentFormat.OpenXml.Packaging;
6+
using DocumentFormat.OpenXml.Spreadsheet;
7+
using MiniExcelLibs.Benchmarks.Utils;
8+
using OfficeOpenXml;
9+
10+
namespace MiniExcelLibs.Benchmarks.BenchmarkSections;
11+
12+
public class CreateXlsxBenchmark : BenchmarkBase
13+
{
14+
[GlobalSetup]
15+
public void SetUp()
16+
{
17+
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
18+
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
19+
}
20+
21+
[Benchmark(Description = "MiniExcel Create Xlsx")]
22+
public void MiniExcelCreateTest()
23+
{
24+
using var path = AutoDeletingPath.Create();
25+
MiniExcel.SaveAs(path.FilePath, GetValue());
26+
}
27+
28+
[Benchmark(Description = "ClosedXml Create Xlsx")]
29+
public void ClosedXmlCreateTest()
30+
{
31+
using var path = AutoDeletingPath.Create();
32+
using var wb = new XLWorkbook();
33+
34+
var ws = wb.Worksheets.Add("Inserting Data");
35+
ws.Cell(1, 1).InsertData(GetValue());
36+
37+
wb.SaveAs(path.FilePath);
38+
}
39+
40+
[Benchmark(Description = "Epplus Create Xlsx")]
41+
public void EpplusCreateTest()
42+
{
43+
using var path = AutoDeletingPath.Create();
44+
using var excelFile = new ExcelPackage(new FileInfo(path.FilePath));
45+
46+
var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");
47+
worksheet.Cells["A1"].LoadFromCollection(Collection: GetValue(), PrintHeaders: true);
48+
49+
excelFile.Save();
50+
}
51+
52+
[Benchmark(Description = "OpenXmlSdk Create Xlsx by DOM mode")]
53+
public void OpenXmlSdkCreateByDomModeTest()
54+
{
55+
using var path = AutoDeletingPath.Create();
56+
using var spreadsheetDocument = SpreadsheetDocument.Create(path.FilePath, SpreadsheetDocumentType.Workbook);
57+
// By default, AutoSave = true, Editable = true, and Type = xlsx.
58+
59+
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
60+
workbookpart.Workbook = new Workbook();
61+
62+
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
63+
worksheetPart.Worksheet = new Worksheet(new SheetData());
64+
65+
Sheets sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
66+
67+
sheets.Append(new Sheet
68+
{
69+
Id = spreadsheetDocument.WorkbookPart.
70+
GetIdOfPart(worksheetPart),
71+
SheetId = 1,
72+
Name = "Sheet1"
73+
});
74+
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
75+
76+
foreach (var item in GetValue())
77+
{
78+
sheetData!.AppendChild(new Row
79+
{
80+
item.Column1, item.Column2, item.Column3, item.Column4, item.Column5,
81+
item.Column6, item.Column7, item.Column8, item.Column9, item.Column10
82+
});
83+
}
84+
85+
workbookpart.Workbook.Save();
86+
}
87+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System.Text;
2+
using BenchmarkDotNet.Attributes;
3+
using ClosedXML.Excel;
4+
using DocumentFormat.OpenXml.Packaging;
5+
using DocumentFormat.OpenXml.Spreadsheet;
6+
using ExcelDataReader;
7+
using OfficeOpenXml;
8+
9+
namespace MiniExcelLibs.Benchmarks.BenchmarkSections;
10+
11+
public class QueryXlsxBenchmark : BenchmarkBase
12+
{
13+
[GlobalSetup]
14+
public void SetUp()
15+
{
16+
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
17+
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
18+
}
19+
20+
[Benchmark(Description = "MiniExcel QueryFirst")]
21+
public void MiniExcel_QueryFirst_Test()
22+
{
23+
_ = MiniExcel.Query(FilePath).First();
24+
}
25+
26+
[Benchmark(Description = "MiniExcel Query")]
27+
public void MiniExcel_Query()
28+
{
29+
foreach (var _ in MiniExcel.Query(FilePath)) { }
30+
}
31+
32+
[Benchmark(Description = "ExcelDataReader QueryFirst")]
33+
public void ExcelDataReader_QueryFirst_Test()
34+
{
35+
using var stream = File.Open(FilePath, FileMode.Open, FileAccess.Read);
36+
using var reader = ExcelReaderFactory.CreateReader(stream);
37+
38+
List<object> d = [];
39+
reader.Read();
40+
41+
for (var i = 0; i < reader.FieldCount; i++)
42+
d.Add(reader.GetValue(i));
43+
}
44+
45+
[Benchmark(Description = "ExcelDataReader Query")]
46+
public void ExcelDataReader_Query_Test()
47+
{
48+
using var stream = File.Open(FilePath, FileMode.Open, FileAccess.Read);
49+
using var reader = ExcelReaderFactory.CreateReader(stream);
50+
51+
while (reader.Read())
52+
{
53+
List<object> d = [];
54+
for (var i = 0; i < reader.FieldCount; i++)
55+
d.Add(reader.GetValue(i));
56+
}
57+
}
58+
59+
[Benchmark(Description = "Epplus QueryFirst")]
60+
public void Epplus_QueryFirst_Test()
61+
{
62+
using var p = new ExcelPackage(new FileInfo(FilePath));
63+
p.Workbook.Worksheets[0].Row(1);
64+
}
65+
66+
[Benchmark(Description = "Epplus Query")]
67+
public void Epplus_Query_Test()
68+
{
69+
// [How do I iterate through rows in an excel table using epplus? - Stack Overflow] (https://stackoverflow.com/questions/21742038/how-do-i-iterate-through-rows-in-an-excel-table-using-epplus)
70+
71+
using var p = new ExcelPackage(new FileInfo(FilePath));
72+
73+
var workSheet = p.Workbook.Worksheets[0];
74+
var start = workSheet.Dimension.Start;
75+
var end = workSheet.Dimension.End;
76+
77+
for (var row = start.Row; row <= end.Row; row++)
78+
{
79+
for (var col = start.Column; col <= end.Column; col++)
80+
{
81+
object cellValue = workSheet.Cells[row, col].Text;
82+
}
83+
}
84+
}
85+
86+
[Benchmark(Description = "ClosedXml QueryFirst")]
87+
public void ClosedXml_QueryFirst_Test()
88+
{
89+
using var workbook = new XLWorkbook(FilePath);
90+
workbook.Worksheet(1).Row(1);
91+
}
92+
93+
[Benchmark(Description = "ClosedXml Query")]
94+
public void ClosedXml_Query_Test()
95+
{
96+
using var workbook = new XLWorkbook(FilePath);
97+
workbook.Worksheet(1).Rows();
98+
}
99+
100+
[Benchmark(Description = "OpenXmlSDK QueryFirst")]
101+
public void OpenXmlSDK_QueryFirst_Test()
102+
{
103+
using var spreadsheetDocument = SpreadsheetDocument.Open(FilePath, false);
104+
105+
var workbookPart = spreadsheetDocument.WorkbookPart;
106+
var worksheetPart = workbookPart!.WorksheetParts.First();
107+
108+
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
109+
var firstRow = sheetData.Elements<Row>().First();
110+
}
111+
112+
[Benchmark(Description = "OpenXmlSDK Query")]
113+
public void OpenXmlSDK_Query_Test()
114+
{
115+
using var spreadsheetDocument = SpreadsheetDocument.Open(FilePath, false);
116+
117+
var workbookPart = spreadsheetDocument.WorkbookPart;
118+
var worksheetPart = workbookPart!.WorksheetParts.First();
119+
120+
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
121+
var firstRow = sheetData.Elements<Row>().ToList();
122+
}
123+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using BenchmarkDotNet.Attributes;
2+
using ClosedXML.Report;
3+
using MiniExcelLibs.Benchmarks.Utils;
4+
5+
namespace MiniExcelLibs.Benchmarks.BenchmarkSections;
6+
7+
public class TemplateXlsxBenchmark : BenchmarkBase
8+
{
9+
[Benchmark(Description = "MiniExcel Template Generate")]
10+
public void MiniExcel_Template_Generate_Test()
11+
{
12+
const string templatePath = "TestTemplateBasicIEmumerableFill.xlsx";
13+
14+
using var path = AutoDeletingPath.Create();
15+
var value = new
16+
{
17+
employees = Enumerable.Range(1, RowCount)
18+
.Select(s => new
19+
{
20+
name = "Jack",
21+
department = "HR"
22+
})
23+
};
24+
25+
MiniExcel.SaveAsByTemplate(path.FilePath, templatePath, value);
26+
}
27+
28+
[Benchmark(Description = "ClosedXml.Report Template Generate")]
29+
public void ClosedXml_Report_Template_Generate_Test()
30+
{
31+
const string templatePath = "TestTemplateBasicIEmumerableFill_ClosedXML_Report.xlsx";
32+
33+
using var path = AutoDeletingPath.Create();
34+
var value = new
35+
{
36+
employees = Enumerable.Range(1, RowCount)
37+
.Select(_ => new
38+
{
39+
name = "Jack",
40+
department = "HR"
41+
})
42+
};
43+
44+
var template = new XLTemplate(templatePath);
45+
template.AddVariable(value);
46+
template.Generate();
47+
48+
template.SaveAs(path.FilePath);
49+
}
50+
}

benchmarks/MiniExcel.Benchmarks/XlsxAsyncBenchmark.cs renamed to benchmarks/MiniExcel.Benchmarks/BenchmarkSections/XlsxAsyncBenchmark.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using BenchmarkDotNet.Attributes;
22
using MiniExcelLibs.Benchmarks.Utils;
33

4-
namespace MiniExcelLibs.Benchmarks;
4+
namespace MiniExcelLibs.Benchmarks.BenchmarkSections;
55

66
public class XlsxAsyncBenchmark : BenchmarkBase
77
{
@@ -22,7 +22,7 @@ public async Task MiniExcel_Template_Generate_Async_Test()
2222
using var path = AutoDeletingPath.Create();
2323
var value = new
2424
{
25-
employees = Enumerable.Range(1, rowCount)
25+
employees = Enumerable.Range(1, RowCount)
2626
.Select(s => new
2727
{
2828
name = "Jack",

benchmarks/MiniExcel.Benchmarks/MiniExcel.Benchmarks.csproj

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,21 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23-
<ProjectReference Include="..\..\src\MiniExcel\MiniExcelLibs.csproj" />
23+
<None Update="Test1,000,000x10.xlsx" CopyToOutputDirectory="PreserveNewest" />
24+
<None Update="Test10,000x10.xlsx" CopyToOutputDirectory="PreserveNewest" />
25+
<None Update="Test100,000x10.xlsx" CopyToOutputDirectory="PreserveNewest" />
26+
<None Update="Test10x10.xlsx" CopyToOutputDirectory="PreserveNewest" />
27+
<None Update="Test100x10.xlsx" CopyToOutputDirectory="PreserveNewest" />
28+
<None Update="TestTemplateBasicIEmumerableFill.xlsx" CopyToOutputDirectory="PreserveNewest" />
29+
<None Update="TestTemplateBasicIEmumerableFill_ClosedXML_Report.xlsx" CopyToOutputDirectory="PreserveNewest" />
2430
</ItemGroup>
2531

2632
<ItemGroup>
27-
<None Update="Test1,000,000x10.xlsx">
28-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
29-
</None>
30-
<None Update="Test10,000x10.xlsx">
31-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
32-
</None>
33-
<None Update="Test100,000x10.xlsx">
34-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
35-
</None>
36-
<None Update="Test10x10.xlsx">
37-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
38-
</None>
39-
<None Update="Test100x10.xlsx">
40-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
41-
</None>
42-
<None Update="TestTemplateBasicIEmumerableFill.xlsx">
43-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
44-
</None>
45-
<None Update="TestTemplateBasicIEmumerableFill_ClosedXML_Report.xlsx">
46-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
47-
</None>
33+
<Folder Include="Properties\" />
4834
</ItemGroup>
4935

5036
<ItemGroup>
51-
<Folder Include="Properties\" />
37+
<ProjectReference Include="..\..\src\MiniExcel\MiniExcelLibs.csproj" />
5238
</ItemGroup>
5339

5440
</Project>

0 commit comments

Comments
 (0)