NPOI 导出 excel 性能测试
Intro#
网上看到很多人说 NPOI 的性能不行,自己写了一个 NPOI 的扩展库,于是想尝试看看 NPOI 的性能究竟怎么样,道听途说始终不如自己动手一试。
测试环境#
测试工具:
- BenchmarkDotNet v0.11.5
- EPPlus.Core.Extensions v2.3.2
- EPPlus v4.5.3.1
- NPOI 2.4.1
测试代码:(Github 源码)
[SimpleJob(launchCount: 1, warmupCount: 1, targetCount: 5)] [MemoryDiagnoser] [MinColumn, MaxColumn, MeanColumn, MedianColumn] public class WorkbookBasicTest { private const int ColsCount = 10; [Params(10000, 30000, 50000, 65535)] public int RowsCount; [Benchmark(Baseline = true)] public byte[] NpoiXlsWorkbookInit() { var workbook = ExcelHelper.PrepareWorkbook(ExcelFormat.Xls); var sheet = workbook.CreateSheet("tempSheet"); for (var i = 0; i < RowsCount; i++) { var row = sheet.CreateRow(i); for (var j = 0; j < ColsCount; j++) { var cell = row.CreateCell(j); cell.SetCellValue($"as ({i}, {j}) sa"); } } return workbook.ToExcelBytes(); } [Benchmark] [MethodImpl(MethodImplOptions.NoInlining)] public byte[] NpoiXlsxWorkbookInit() { var workbook = ExcelHelper.PrepareWorkbook(ExcelFormat.Xlsx); var sheet = workbook.CreateSheet("tempSheet"); for (var i = 0; i < RowsCount; i++) { var row = sheet.CreateRow(i); for (var j = 0; j < ColsCount; j++) { var cell = row.CreateCell(j); cell.SetCellValue($"as ({i}, {j}) sa"); } } return workbook.ToExcelBytes(); } [Benchmark] [MethodImpl(MethodImplOptions.NoInlining)] public byte[] EpplusWorkbookInit() { var excel = new ExcelPackage(); var sheet = excel.Workbook.Worksheets.Add("tempSheet"); for (var i = 1; i <= RowsCount; i++) { for (var j = 1; j <= ColsCount; j++) { sheet.Cells[i, j].Value = $"as ({i}, {j}) sa"; } } return excel.GetAsByteArray(); } }
测试结果#
在 Github 上查看结果 https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/perf/WeihanLi.Npoi.Benchmark/BenchmarkDotNet.Artifacts/results/WeihanLi.Npoi.Benchmark.WorkbookBasicTest-report-github.md
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362 Intel Core i5-3470 CPU 3.20GHz (Ivy Bridge), 1 CPU, 4 logical and 4 physical cores .NET Core SDK=3.0.100 [Host] : .NET Core 2.2.6 (CoreCLR 4.6.27817.03, CoreFX 4.6.27818.02), 64bit RyuJIT Job-CBYTBY : .NET Core 2.2.6 (CoreCLR 4.6.27817.03, CoreFX 4.6.27818.02), 64bit RyuJIT IterationCount=5 LaunchCount=1 WarmupCount=1
Method | RowsCount | Mean | Error | StdDev | Min | Max | Median | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
NpoiXlsWorkbookInit | 10000 | 324.7 ms | 1.583 ms | 0.4110 ms | 324.3 ms | 325.4 ms | 324.6 ms | 1.00 | 0.00 | 10000.0000 | 5000.0000 | 2000.0000 | 78.6 MB |
NpoiXlsxWorkbookInit | 10000 | 1,369.0 ms | 73.747 ms | 19.1517 ms | 1,341.3 ms | 1,384.4 ms | 1,381.1 ms | 4.22 | 0.06 | 57000.0000 | 14000.0000 | 4000.0000 | 306.45 MB |
EpplusWorkbookInit | 10000 | 552.9 ms | 12.740 ms | 3.3085 ms | 549.7 ms | 557.7 ms | 552.4 ms | 1.70 | 0.01 | 18000.0000 | 7000.0000 | 3000.0000 | 121.05 MB |
NpoiXlsWorkbookInit | 30000 | 1,222.4 ms | 33.717 ms | 8.7562 ms | 1,209.0 ms | 1,233.1 ms | 1,222.5 ms | 1.00 | 0.00 | 29000.0000 | 11000.0000 | 3000.0000 | 235.03 MB |
NpoiXlsxWorkbookInit | 30000 | 4,226.2 ms | 299.833 ms | 77.8658 ms | 4,109.5 ms | 4,308.6 ms | 4,257.2 ms | 3.46 | 0.08 | 174000.0000 | 34000.0000 | 6000.0000 | 913.9 MB |
EpplusWorkbookInit | 30000 | 1,695.4 ms | 31.751 ms | 8.2457 ms | 1,686.3 ms | 1,706.5 ms | 1,694.2 ms | 1.39 | 0.02 | 48000.0000 | 17000.0000 | 5000.0000 | 358.51 MB |
NpoiXlsWorkbookInit | 50000 | 2,323.5 ms | 236.041 ms | 61.2990 ms | 2,286.0 ms | 2,431.9 ms | 2,294.2 ms | 1.00 | 0.00 | 47000.0000 | 18000.0000 | 4000.0000 | 417.1 MB |
NpoiXlsxWorkbookInit | 50000 | 7,055.2 ms | 279.256 ms | 72.5218 ms | 6,982.8 ms | 7,150.2 ms | 7,027.2 ms | 3.04 | 0.10 | 288000.0000 | 51000.0000 | 6000.0000 | 1545.32 MB |
EpplusWorkbookInit | 50000 | 2,806.9 ms | 56.266 ms | 14.6121 ms | 2,792.9 ms | 2,829.1 ms | 2,804.6 ms | 1.21 | 0.03 | 79000.0000 | 27000.0000 | 7000.0000 | 578.46 MB |
NpoiXlsWorkbookInit | 65535 | 3,646.8 ms | 131.129 ms | 34.0537 ms | 3,603.0 ms | 3,696.3 ms | 3,642.5 ms | 1.00 | 0.00 | 61000.0000 | 21000.0000 | 4000.0000 | 504.46 MB |
NpoiXlsxWorkbookInit | 65535 | 9,295.6 ms | 486.761 ms | 126.4104 ms | 9,163.3 ms | 9,468.6 ms | 9,330.5 ms | 2.55 | 0.04 | 390000.0000 | 67000.0000 | 8000.0000 | 2048.14 MB |
EpplusWorkbookInit | 65535 | 3,721.6 ms | 124.945 ms | 32.4478 ms | 3,680.7 ms | 3,766.8 ms | 3,714.1 ms | 1.02 | 0.01 | 102000.0000 | 35000.0000 | 8000.0000 | 747.85 MB |
从上面的测试结果来看,npoi 导出 xls 的性能还是相当好的,无论是所用时间还是内存都占优势,只是 xls 一个 sheet 最多 65535 行数据,所以测试数据最多只有 65535,其次就是 epplus 导出 xlsx,最次是 npoi 导出 xlsx 了。
测试结论#
如果使用 NPOI 导出建议导出 xls
,如果要导出数据较多,可以导出 csv ,如果看了另外一个 csv 导出的测试,csv 导出性能要比 excel 好很多,如果实在是要导出 excel,导入 xls
的话就分多个 sheet 处理,如果一定要导出 xlsx
格式的 excel ,推荐用 epplus 来处理,相比 npoi 导出 xlsx
性能更好,内存占用更少
Reference#
- https://benchmarkdotnet.org/
- https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/perf/WeihanLi.Npoi.Benchmark/WorkbookBasicTest.cs