mirror of
https://gitee.com/dotnetchina/MiniExcel.git
synced 2024-11-29 18:38:08 +08:00
Benchmark coderefacturing
This commit is contained in:
parent
6a27a4e93a
commit
cb185269b3
@ -74,7 +74,7 @@ IterationCount=3 LaunchCount=3 WarmupCount=3
|
||||
```
|
||||
|
||||
#### Import/Query Excel
|
||||
Logic : (benchmarks/MiniExcel.Benchmarks/Test1%2C000%2C000x10.xlsx) as performance test basic file,A total of 10,000,000 "HelloWorld" with a file size of 23 MB
|
||||
Logic : [**Test1,000,000x10.xlsx**](benchmarks/MiniExcel.Benchmarks/Test1%2C000%2C000x10.xlsx) as performance test basic file, 1,000,000 rows * 10 columns "HelloWorld" cells, 23 MB file size
|
||||
|
||||
|
||||
| Library | Method | Max Memory Usage | Mean |
|
||||
|
@ -75,7 +75,7 @@ IterationCount=3 LaunchCount=3 WarmupCount=3
|
||||
```
|
||||
|
||||
#### 导入、查询 Excel 比较
|
||||
逻辑 : 以 [**Test1,000,000x10.xlsx**](benchmarks/MiniExcel.Benchmarks/Test1%2C000%2C000x10.xlsx) 做基准与主流框架做性能测试,总共 1千万笔 "HelloWorld",文件大小 23 MB
|
||||
逻辑 : 以 [**Test1,000,000x10.xlsx**](benchmarks/MiniExcel.Benchmarks/Test1%2C000%2C000x10.xlsx) 做基准与主流框架做性能测试,总共 1,000,000 行 * 10 列笔 "HelloWorld",文件大小 23 MB
|
||||
|
||||
|
||||
| Library | Method | 最大内存耗用 | 平均时间 |
|
||||
|
@ -71,7 +71,8 @@ IterationCount=3 LaunchCount=3 WarmupCount=3
|
||||
```
|
||||
|
||||
#### 導入、查詢 Excel 比較
|
||||
邏輯 : 以 [**Test1,000,000x10.xlsx**](benchmarks/MiniExcel.Benchmarks/Test1%2C000%2C000x10.xlsx) 做基準與主流框架做性能測試,總共 1千萬筆 "HelloWorld",文件大小 23 MB
|
||||
|
||||
邏輯 : 以 [**Test1,000,000x10.xlsx**](benchmarks/MiniExcel.Benchmarks/Test1%2C000%2C000x10.xlsx) 做基準與主流框架做性能測試,總共 1,000,000 行 * 10 列筆 "HelloWorld",文件大小 23 MB
|
||||
|
||||
|
||||
| Library | Method | 最大記憶體耗用 | 平均時間 |
|
||||
|
36
benchmarks/MiniExcel.Benchmarks/BenchmarkBase.cs
Normal file
36
benchmarks/MiniExcel.Benchmarks/BenchmarkBase.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Order;
|
||||
|
||||
namespace MiniExcelLibs.Benchmarks
|
||||
{
|
||||
public abstract class BenchmarkBase
|
||||
{
|
||||
//public const string filePath = @"Test10x10.xlsx";
|
||||
//public const int rowCount = 1_0;
|
||||
|
||||
public const string filePath = @"Test1,000,000x10.xlsx";
|
||||
public const int rowCount = 1_000_000;
|
||||
|
||||
public IEnumerable<DemoDto> Getvalue()
|
||||
{
|
||||
return Enumerable.Range(1, rowCount).Select(s => new DemoDto());
|
||||
}
|
||||
|
||||
public class DemoDto
|
||||
{
|
||||
public string Column1 { get; set; } = "Hello World";
|
||||
public string Column2 { get; set; } = "Hello World";
|
||||
public string Column3 { get; set; } = "Hello World";
|
||||
public string Column4 { get; set; } = "Hello World";
|
||||
public string Column5 { get; set; } = "Hello World";
|
||||
public string Column6 { get; set; } = "Hello World";
|
||||
public string Column7 { get; set; } = "Hello World";
|
||||
public string Column8 { get; set; } = "Hello World";
|
||||
public string Column9 { get; set; } = "Hello World";
|
||||
public string Column10 { get; set; } = "Hello World";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
using BenchmarkDotNet.Analysers;
|
||||
using BenchmarkDotNet.Columns;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Exporters;
|
||||
using BenchmarkDotNet.Filters;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Loggers;
|
||||
using BenchmarkDotNet.Order;
|
||||
using BenchmarkDotNet.Reports;
|
||||
using BenchmarkDotNet.Toolchains.InProcess.Emit;
|
||||
using BenchmarkDotNet.Validators;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace MiniExcelLibs.Benchmarks
|
||||
{
|
||||
public class DebugConfig : ManualConfig
|
||||
{
|
||||
public new IOrderer Orderer => DefaultOrderer.Instance;
|
||||
|
||||
public new SummaryStyle SummaryStyle => SummaryStyle.Default;
|
||||
|
||||
public new ConfigUnionRule UnionRule => ConfigUnionRule.Union;
|
||||
|
||||
public new string ArtifactsPath => Path.Combine(Directory.GetCurrentDirectory(), "BenchmarkDotNet.Artifacts");
|
||||
|
||||
public new CultureInfo CultureInfo => null;
|
||||
|
||||
public new ConfigOptions Options => ConfigOptions.KeepBenchmarkFiles | ConfigOptions.DisableOptimizationsValidator;
|
||||
|
||||
public new IEnumerable<Job> GetJobs()
|
||||
{
|
||||
return new Job[1]
|
||||
{
|
||||
JobMode<Job>.Default.WithToolchain(new InProcessEmitToolchain(TimeSpan.FromHours(1.0), logOutput: true))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public new IEnumerable<IValidator> GetValidators()
|
||||
{
|
||||
return Array.Empty<IValidator>();
|
||||
}
|
||||
|
||||
public new IEnumerable<IColumnProvider> GetColumnProviders()
|
||||
{
|
||||
return DefaultColumnProviders.Instance;
|
||||
}
|
||||
|
||||
public new IEnumerable<IExporter> GetExporters()
|
||||
{
|
||||
return Array.Empty<IExporter>();
|
||||
}
|
||||
|
||||
public new IEnumerable<ILogger> GetLoggers()
|
||||
{
|
||||
return new ILogger[1]
|
||||
{
|
||||
ConsoleLogger.Default
|
||||
};
|
||||
}
|
||||
|
||||
public new IEnumerable<IDiagnoser> GetDiagnosers()
|
||||
{
|
||||
return Array.Empty<IDiagnoser>();
|
||||
}
|
||||
|
||||
public new IEnumerable<IAnalyser> GetAnalysers()
|
||||
{
|
||||
return Array.Empty<IAnalyser>();
|
||||
}
|
||||
|
||||
public new IEnumerable<HardwareCounter> GetHardwareCounters()
|
||||
{
|
||||
return Array.Empty<HardwareCounter>();
|
||||
}
|
||||
|
||||
public new IEnumerable<IFilter> GetFilters()
|
||||
{
|
||||
return Array.Empty<IFilter>();
|
||||
}
|
||||
|
||||
public new IEnumerable<BenchmarkLogicalGroupRule> GetLogicalGroupRules()
|
||||
{
|
||||
return Array.Empty<BenchmarkLogicalGroupRule>();
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Test1,000,000x10.xlsx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Test10,000x10.xlsx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
@ -1,20 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Order;
|
||||
using BenchmarkDotNet.Running;
|
||||
using ClosedXML.Excel;
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using ExcelDataReader;
|
||||
using MiniExcelLibs;
|
||||
using OfficeOpenXml;
|
||||
|
||||
@ -24,342 +12,12 @@ namespace MiniExcelLibs.Benchmarks
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
#if !DEBUG
|
||||
BenchmarkSwitcher.FromTypes(new[]{typeof(XlsxBenchmark)}).Run(args, new Config());
|
||||
#if DEBUG
|
||||
new XlsxBenchmark().Epplus_QueryFirst_Test();
|
||||
#else
|
||||
BenchmarkSwitcher.FromTypes(new[] { typeof(XlsxBenchmark) }).Run(args, new DebugInProcessConfig() );
|
||||
//new TemplateXlsxBenchmark().MiniExcel_Template_Generate_Test();
|
||||
//new XlsxBenchmark().MiniExcelCreateTest();
|
||||
BenchmarkSwitcher.FromTypes(new[]{typeof(XlsxBenchmark)}).Run(args, new Config());
|
||||
#endif
|
||||
Console.Read();
|
||||
}
|
||||
}
|
||||
|
||||
[BenchmarkCategory("Framework")]
|
||||
[MemoryDiagnoser]
|
||||
[SimpleJob(launchCount: 1, warmupCount: 1, targetCount: 1,invocationCount:1,baseline:false)]
|
||||
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
|
||||
public abstract class BenchmarkBase
|
||||
{
|
||||
#if !DEBUG
|
||||
public const string filePath = @"Test10,000x10.xlsx";
|
||||
public const int runCount = 1_000_000;
|
||||
#else
|
||||
public const string filePath = @"Test100x10.xlsx";
|
||||
public const int runCount = 10;
|
||||
#endif
|
||||
|
||||
//public const string filePath = @"Test10x10.xlsx";
|
||||
//public const int runCount = 10;
|
||||
|
||||
public static IEnumerable<Demo> GetValues()
|
||||
{
|
||||
#if !DEBUG
|
||||
return Enumerable.Range(1, runCount).Select(s => new Demo());
|
||||
#else
|
||||
return Enumerable.Range(1, runCount).Select(s => new Demo());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class XlsxBenchmark: BenchmarkBase
|
||||
{
|
||||
[GlobalSetup]
|
||||
public void SetUp()
|
||||
{
|
||||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Template Generate")]
|
||||
public void MiniExcel_Template_Generate_Test()
|
||||
{
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
const string templatePath = @"TestTemplateBasicIEmumerableFill.xlsx";
|
||||
var value = new
|
||||
{
|
||||
employees = Enumerable.Range(1, runCount).Select(s => new { name = "Jack", department = "HR" })
|
||||
};
|
||||
MiniExcel.SaveAsByTemplate(path, templatePath, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Async Template Generate")]
|
||||
public async Task MiniExcel_Template_Generate_Async_Test()
|
||||
{
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
const string templatePath = @"TestTemplateBasicIEmumerableFill.xlsx";
|
||||
var value = new
|
||||
{
|
||||
employees = Enumerable.Range(1, runCount).Select(s => new { name = "Jack", department = "HR" })
|
||||
};
|
||||
await MiniExcel.SaveAsByTemplateAsync(path, templatePath, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml.Report Template Generate")]
|
||||
public void ClosedXml_Report_Template_Generate_Test()
|
||||
{
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
var templatePath = @"TestTemplateBasicIEmumerableFill_ClosedXML_Report.xlsx";
|
||||
var template = new ClosedXML.Report.XLTemplate(templatePath);
|
||||
var value = new
|
||||
{
|
||||
employees = Enumerable.Range(1, runCount).Select(s => new { name = "Jack", department = "HR" })
|
||||
};
|
||||
template.AddVariable(value);
|
||||
template.Generate();
|
||||
template.SaveAs(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel QueryFirst")]
|
||||
public void MiniExcel_QueryFirst_Test()
|
||||
{
|
||||
MiniExcel.Query(filePath).First();
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Query")]
|
||||
public void MiniExcel_Query()
|
||||
{
|
||||
foreach (var item in MiniExcel.Query(filePath))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ExcelDataReader QueryFirst")]
|
||||
public void ExcelDataReader_QueryFirst_Test()
|
||||
{
|
||||
#if DEBUG
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
|
||||
using (var reader = ExcelReaderFactory.CreateReader(stream))
|
||||
{
|
||||
var d = new List<object>();
|
||||
reader.Read();
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
d.Add(reader.GetValue(i));
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ExcelDataReader Query")]
|
||||
public void ExcelDataReader_Query_Test()
|
||||
{
|
||||
#if DEBUG
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
|
||||
using (var reader = ExcelReaderFactory.CreateReader(stream))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var d = new List<object>();
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
d.Add(reader.GetValue(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Epplus QueryFirst")]
|
||||
public void Epplus_QueryFirst_Test()
|
||||
{
|
||||
#if DEBUG
|
||||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||||
#endif
|
||||
using (var p = new ExcelPackage(new FileInfo(filePath)))
|
||||
{
|
||||
p.Workbook.Worksheets[0].Row(1);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Epplus Query")]
|
||||
public void Epplus_Query_Test()
|
||||
{
|
||||
#if DEBUG
|
||||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||||
#endif
|
||||
// [c# - 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)
|
||||
using (var p = new ExcelPackage(new FileInfo(filePath)))
|
||||
{
|
||||
var workSheet = p.Workbook.Worksheets[0];
|
||||
var start = workSheet.Dimension.Start;
|
||||
var end = workSheet.Dimension.End;
|
||||
for (int row = start.Row; row <= end.Row; row++)
|
||||
{ // Row by row...
|
||||
for (int col = start.Column; col <= end.Column; col++)
|
||||
{ // ... Cell by cell...
|
||||
object cellValue = workSheet.Cells[row, col].Text; // This got me the actual value I needed.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml QueryFirst")]
|
||||
public void ClosedXml_QueryFirst_Test()
|
||||
{
|
||||
using (var workbook = new XLWorkbook(filePath))
|
||||
{
|
||||
workbook.Worksheet(1).Row(1);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml Query")]
|
||||
public void ClosedXml_Query_Test()
|
||||
{
|
||||
using (var workbook = new XLWorkbook(filePath))
|
||||
{
|
||||
workbook.Worksheet(1).Rows();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "OpenXmlSDK QueryFirst")]
|
||||
public void OpenXmlSDK_QueryFirst_Test()
|
||||
{
|
||||
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false))
|
||||
{
|
||||
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
|
||||
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
|
||||
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
|
||||
var firstRow = sheetData.Elements<Row>().First();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "OpenXmlSDK Query")]
|
||||
public void OpenXmlSDK_Query_Test()
|
||||
{
|
||||
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false))
|
||||
{
|
||||
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
|
||||
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
|
||||
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
|
||||
var firstRow = sheetData.Elements<Row>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Create Xlsx")]
|
||||
public void MiniExcelCreateTest()
|
||||
{
|
||||
var values = GetValues();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var stream = File.Create(path))
|
||||
stream.SaveAs(values);
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Async Create Xlsx")]
|
||||
public async Task MiniExcelCreateAsyncTest()
|
||||
{
|
||||
var values = GetValues();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var stream = File.Create(path))
|
||||
await stream.SaveAsAsync(values);
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml Create Xlsx")]
|
||||
public void ClosedXmlCreateTest()
|
||||
{
|
||||
var values = GetValues();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Inserting Data");
|
||||
ws.Cell(1, 1).InsertData(values);
|
||||
wb.SaveAs(path);
|
||||
}
|
||||
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
|
||||
[Benchmark(Description = "Epplus Create Xlsx")]
|
||||
public void EpplusCreateTest()
|
||||
{
|
||||
#if DEBUG
|
||||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||||
#endif
|
||||
var values = GetValues();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var excelFile = new ExcelPackage(new FileInfo(path)))
|
||||
{
|
||||
var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");
|
||||
worksheet.Cells["A1"].LoadFromCollection(Collection: values, PrintHeaders: true);
|
||||
excelFile.Save();
|
||||
}
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "OpenXmlSdk Create Xlsx")]
|
||||
public void OpenXmlSdkCreateTest()
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
// Create a spreadsheet document by supplying the filepath.
|
||||
// By default, AutoSave = true, Editable = true, and Type = xlsx.
|
||||
|
||||
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook))
|
||||
{
|
||||
// Add a WorkbookPart to the document.
|
||||
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
|
||||
workbookpart.Workbook = new Workbook();
|
||||
|
||||
// Add a WorksheetPart to the WorkbookPart.
|
||||
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
|
||||
worksheetPart.Worksheet = new Worksheet(new SheetData());
|
||||
|
||||
// Add Sheets to the Workbook.
|
||||
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
|
||||
AppendChild<Sheets>(new Sheets());
|
||||
|
||||
// Append a new worksheet and associate it with the workbook.
|
||||
Sheet sheet = new Sheet()
|
||||
{
|
||||
Id = spreadsheetDocument.WorkbookPart.
|
||||
GetIdOfPart(worksheetPart),
|
||||
SheetId = 1,
|
||||
Name = "Sheet1"
|
||||
};
|
||||
sheets.Append(sheet);
|
||||
|
||||
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
|
||||
foreach (var item in GetValues())
|
||||
{
|
||||
var row = new Row();
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text1), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text2), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text3), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text4), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text5), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text6), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text7), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text8), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text9), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Text10), DataType = CellValues.String });
|
||||
sheetData.AppendChild(row);
|
||||
}
|
||||
|
||||
workbookpart.Workbook.Save();
|
||||
|
||||
}
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
public class Demo
|
||||
{
|
||||
public string Text1 { get; set; } = "Hello World";
|
||||
public string Text2 { get; set; } = "Hello World";
|
||||
public string Text3 { get; set; } = "Hello World";
|
||||
public string Text4 { get; set; } = "Hello World";
|
||||
public string Text5 { get; set; } = "Hello World";
|
||||
public string Text6 { get; set; } = "Hello World";
|
||||
public string Text7 { get; set; } = "Hello World";
|
||||
public string Text8 { get; set; } = "Hello World";
|
||||
public string Text9 { get; set; } = "Hello World";
|
||||
public string Text10 { get; set; } = "Hello World";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\netcoreapp3.1\publish\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
</PropertyGroup>
|
||||
</Project>
|
34
benchmarks/MiniExcel.Benchmarks/XlsxAsyncBenchmark.cs
Normal file
34
benchmarks/MiniExcel.Benchmarks/XlsxAsyncBenchmark.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
namespace MiniExcelLibs.Benchmarks
|
||||
{
|
||||
public class XlsxAsyncBenchmark : BenchmarkBase
|
||||
{
|
||||
[Benchmark(Description = "MiniExcel Async Create Xlsx")]
|
||||
public async Task MiniExcelCreateAsyncTest()
|
||||
{
|
||||
var value = Getvalue();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var stream = File.Create(path))
|
||||
await stream.SaveAsAsync(value);
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Async Template Generate")]
|
||||
public async Task MiniExcel_Template_Generate_Async_Test()
|
||||
{
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
const string templatePath = @"TestTemplateBasicIEmumerableFill.xlsx";
|
||||
var value = new
|
||||
{
|
||||
employees = Enumerable.Range(1, rowCount).Select(s => new { name = "Jack", department = "HR" })
|
||||
};
|
||||
await MiniExcel.SaveAsByTemplateAsync(path, templatePath, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
259
benchmarks/MiniExcel.Benchmarks/XlsxBenchmark.cs
Normal file
259
benchmarks/MiniExcel.Benchmarks/XlsxBenchmark.cs
Normal file
@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using ClosedXML.Excel;
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using ExcelDataReader;
|
||||
using OfficeOpenXml;
|
||||
|
||||
namespace MiniExcelLibs.Benchmarks
|
||||
{
|
||||
public class XlsxBenchmark : BenchmarkBase
|
||||
{
|
||||
[GlobalSetup]
|
||||
public void SetUp()
|
||||
{
|
||||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Template Generate")]
|
||||
public void MiniExcel_Template_Generate_Test()
|
||||
{
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
const string templatePath = @"TestTemplateBasicIEmumerableFill.xlsx";
|
||||
var value = new
|
||||
{
|
||||
employees = Enumerable.Range(1, rowCount).Select(s => new { name = "Jack", department = "HR" })
|
||||
};
|
||||
MiniExcel.SaveAsByTemplate(path, templatePath, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml.Report Template Generate")]
|
||||
public void ClosedXml_Report_Template_Generate_Test()
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
var templatePath = @"TestTemplateBasicIEmumerableFill_ClosedXML_Report.xlsx";
|
||||
var template = new ClosedXML.Report.XLTemplate(templatePath);
|
||||
var value = new
|
||||
{
|
||||
employees = Enumerable.Range(1, rowCount).Select(s => new { name = "Jack", department = "HR" })
|
||||
};
|
||||
template.AddVariable(value);
|
||||
template.Generate();
|
||||
template.SaveAs(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel QueryFirst")]
|
||||
public void MiniExcel_QueryFirst_Test()
|
||||
{
|
||||
MiniExcel.Query(filePath).First();
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Query")]
|
||||
public void MiniExcel_Query()
|
||||
{
|
||||
foreach (var item in MiniExcel.Query(filePath))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ExcelDataReader QueryFirst")]
|
||||
public void ExcelDataReader_QueryFirst_Test()
|
||||
{
|
||||
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
|
||||
using (var reader = ExcelReaderFactory.CreateReader(stream))
|
||||
{
|
||||
var d = new List<object>();
|
||||
reader.Read();
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
d.Add(reader.GetValue(i));
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ExcelDataReader Query")]
|
||||
public void ExcelDataReader_Query_Test()
|
||||
{
|
||||
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
|
||||
using (var reader = ExcelReaderFactory.CreateReader(stream))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var d = new List<object>();
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
d.Add(reader.GetValue(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Epplus QueryFirst")]
|
||||
public void Epplus_QueryFirst_Test()
|
||||
{
|
||||
using (var p = new ExcelPackage(new FileInfo(filePath)))
|
||||
{
|
||||
p.Workbook.Worksheets[0].Row(1);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Epplus Query")]
|
||||
public void Epplus_Query_Test()
|
||||
{
|
||||
// [c# - 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)
|
||||
using (var p = new ExcelPackage(new FileInfo(filePath)))
|
||||
{
|
||||
var workSheet = p.Workbook.Worksheets[0];
|
||||
var start = workSheet.Dimension.Start;
|
||||
var end = workSheet.Dimension.End;
|
||||
for (int row = start.Row; row <= end.Row; row++)
|
||||
{ // Row by row...
|
||||
for (int col = start.Column; col <= end.Column; col++)
|
||||
{ // ... Cell by cell...
|
||||
object cellValue = workSheet.Cells[row, col].Text; // This got me the actual value I needed.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml QueryFirst")]
|
||||
public void ClosedXml_QueryFirst_Test()
|
||||
{
|
||||
using (var workbook = new XLWorkbook(filePath))
|
||||
{
|
||||
workbook.Worksheet(1).Row(1);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml Query")]
|
||||
public void ClosedXml_Query_Test()
|
||||
{
|
||||
using (var workbook = new XLWorkbook(filePath))
|
||||
{
|
||||
workbook.Worksheet(1).Rows();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "OpenXmlSDK QueryFirst")]
|
||||
public void OpenXmlSDK_QueryFirst_Test()
|
||||
{
|
||||
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false))
|
||||
{
|
||||
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
|
||||
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
|
||||
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
|
||||
var firstRow = sheetData.Elements<Row>().First();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "OpenXmlSDK Query")]
|
||||
public void OpenXmlSDK_Query_Test()
|
||||
{
|
||||
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false))
|
||||
{
|
||||
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
|
||||
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
|
||||
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
|
||||
var firstRow = sheetData.Elements<Row>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(Description = "MiniExcel Create Xlsx")]
|
||||
public void MiniExcelCreateTest()
|
||||
{
|
||||
var value = Getvalue();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
MiniExcel.SaveAs(path, value);
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "ClosedXml Create Xlsx")]
|
||||
public void ClosedXmlCreateTest()
|
||||
{
|
||||
var value = Getvalue();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Inserting Data");
|
||||
ws.Cell(1, 1).InsertData(value);
|
||||
wb.SaveAs(path);
|
||||
}
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
|
||||
[Benchmark(Description = "Epplus Create Xlsx")]
|
||||
public void EpplusCreateTest()
|
||||
{
|
||||
var value = Getvalue();
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
using (var excelFile = new ExcelPackage(new FileInfo(path)))
|
||||
{
|
||||
var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");
|
||||
worksheet.Cells["A1"].LoadFromCollection(Collection: value, PrintHeaders: true);
|
||||
excelFile.Save();
|
||||
}
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "OpenXmlSdk Create xlsx by DOM mode")]
|
||||
public void OpenXmlSdkCreateByDomModeTest()
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
// Create a spreadsheet document by supplying the filepath.
|
||||
// By default, AutoSave = true, Editable = true, and Type = xlsx.
|
||||
|
||||
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook))
|
||||
{
|
||||
// Add a WorkbookPart to the document.
|
||||
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
|
||||
workbookpart.Workbook = new Workbook();
|
||||
|
||||
// Add a WorksheetPart to the WorkbookPart.
|
||||
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
|
||||
worksheetPart.Worksheet = new Worksheet(new SheetData());
|
||||
|
||||
// Add Sheets to the Workbook.
|
||||
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
|
||||
AppendChild<Sheets>(new Sheets());
|
||||
|
||||
// Append a new worksheet and associate it with the workbook.
|
||||
Sheet sheet = new Sheet()
|
||||
{
|
||||
Id = spreadsheetDocument.WorkbookPart.
|
||||
GetIdOfPart(worksheetPart),
|
||||
SheetId = 1,
|
||||
Name = "Sheet1"
|
||||
};
|
||||
sheets.Append(sheet);
|
||||
|
||||
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
|
||||
foreach (var item in Getvalue())
|
||||
{
|
||||
var row = new Row();
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column1), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column2), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column3), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column4), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column5), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column6), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column7), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column8), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column9), DataType = CellValues.String });
|
||||
row.Append(new Cell() { CellValue = new CellValue(item.Column10), DataType = CellValues.String });
|
||||
sheetData.AppendChild(row);
|
||||
}
|
||||
|
||||
workbookpart.Workbook.Save();
|
||||
|
||||
}
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user