我的性能测试函数介绍IEnumerable<object> Measure(Action action, int times = 5){ return Enumerable.Range(1, times).Select(i => { var sw = Stopwatch.StartNew; long memory1 = GC.GetTotalMemory(true); long allocate1 = GC.GetTotalAllocatedBytes(true); { action; } long allocate2 = GC.GetTotalAllocatedBytes(true); long memory2 = GC.GetTotalMemory(true); sw.Stop; return new { 次数 = i, 分配内存 = (allocate2 - allocate1).ToString("N0"), 内存提高 = (memory2 - memory1).ToString("N0"), 耗时 = sw.ElapsedMilliseconds, }; });}除了时间,内存占用实际也是非常非常重要、但容易被人忽略的性能指标 。大家都以为“内存不值钱”,但——
- 一旦访问量大,内存就会瞬间上涨,导致频繁GC,导致性能下降;
- 内存高也会导致服务器分页,这时性能就会急剧下降;
- 吞吐量下降会导致队列排满,此时服务器就会报503等错误,客户就发现服务器“宕机了” 。
在我的性能测试函数中,使用了如下两个函数来测试内存占用:
- GC.GetTotalAllocatedBytes(true) 获取分配内存大小
- GC.GetTotalMemory(true) 获取占用内存大小
通过调用Measure函数,可以测得传入的action的耗时和内存占用 。默认会调用5次,可以从5次测试结果中取出能反映性能的值 。
测试基准
string Export<T>(List<T> data, string path){ PropertyInfo props = typeof(User).GetProperties; string noCache = ; for (var i = 0; i < props.Length; ++i) { noCache = props[i].Name; } for (var i = 0; i < data.Count; ++i) { for (var j = 0; j < props.Length; ++j) { noCache = props[j].GetValue(data[i]).ToString; } } return noCache;}注意:- 我有意使用了反射,这符合我们导出Excel代码简单、易学、好用、好扩展的愿意;
- 我有意使用了泛型T,而不是实际类型,这也让这些代码容易扩展;
- 里面的noCache用来规避编译器优化删除代码的行为
次数分配内存内存提高耗时19,863,5208,71215629,852,592013839,852,592014749,873,0969,24013659,853,936776133 可见,基于反射操作6万/10列数据,每次需要分配约9MB内存,但这些内存都会被快速GC,最终内存提高较少 。这些使用反射的代码运行耗时在130ms-150ms左右 。
各个库的使用和性能表现NPOI
void Export<T>(List<T> data, string path){ IWorkbook workbook = new XSSFWorkbook; ISheet sheet = workbook.CreateSheet("Sheet1"); var headRow = sheet.CreateRow(0); PropertyInfo props = typeof(User).GetProperties; for (var i = 0; i < props.Length; ++i) { headRow.CreateCell(i).SetCellValue(props[i].Name); } for (var i = 0; i < data.Count; ++i) { var row = sheet.CreateRow(i + 1); for (var j = 0; j < props.Length; ++j) { row.CreateCell(j).SetCellValue(props[j].GetValue(data[i]).ToString); } } using var file = File.Create(path); workbook.Write(file);}注意:里面用到了XSSFWorkBook,其中XSSF这个前缀是从Java的POI库传过来的,全称是XML SpreadSheet Format 。
这种前缀在NPOI包中很常见 。
XSSFWorkbook提供了bool Dispose方法,但它未实现(因此千万别调用它):

文章插图
性能测试结果:
次数分配内存内存提高耗时11,598,586,416537,048659021,589,239,7287,7121015531,589,232,056-5,3681030941,589,237,0647,1441035551,589,245,0009,56010594 分配内存稳定在1.48GB的样子,首次内存会提高524KB左右,后面趋于稳定 。首次耗时6秒多,后面稳定在10秒多 。
EPPlus
void Export<T>(List<T> data, string path)
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- .NET如何生成大量随机数据
- Excel中怎么计算出某个日期是星期几
- 使用频率很高的3个Excel函数公式
- Excel新手常见的几种坑,亲测踩中很伤
- 在Excel里面制作一个二维码 做二维码
- .net开源框架简介和通用技术选型建议
- 一组Excel专用小技巧,新手请拿好
- 微信聊天记录怎么导出word?不可错过的微信技巧
- 怎样冻结excel表格的某个区域?
- Excel数据校验有办法
