讲师简介
王鸿,2020 中国 .NET 开发者峰会主论坛讲师,葡萄城表格技术负责人,GcExcel 项目组资深架构师。
自 2014 年起,王鸿老师便始终聚焦于企业高性能表格技术畛域的钻研,为葡萄城设计了全新的表格组件架构,并率领研发团队推出了一款性能在业界当先的电子表格组件 GcExcel, 积攒了大量高并发、高可用性表格组件的架构设计教训。
分享内容
12 月 19 日,王鸿老师受邀加入 2020 中国 .NET 开发者大会,与微软、龙芯等知名企业的技术大咖一起,为 50 余万名开发者带来了一场对于《高性能表格技术优化实际》的技术讲座。
在大会上,王鸿老师从葡萄城研发电子表格组件的背景与初衷登程,具体比照了 Excel 与原生 C# 代码的读取性能差别,并总结了若干针对 prototype 原型进行性能调优的伎俩,如缩小垃圾回收的影响、共享对象晋升性能、压缩数据升高内存、充分利用高速缓存等形式。
本期,葡萄城公开课将持续邀请王鸿老师负责演讲嘉宾,为错过大会的同学深刻解说葡萄城表格组件的性能调优实际,以及葡萄城表格技术的落地产物 SpreadJS 和 GcExcel,曾经收听过的同学仍能够报名加入,获取与王鸿老师在线交换的机会。
扫码上图二维码,收费报名加入
Excel 读取 1 亿个单元格的极限性能是 34 秒
为了测试 Excel 文件的读取性能极限,王鸿老师应用了 StopWatch 函数来监听 Excel 的关上工夫,测试对象为一个蕴含 30 列、1,000,000 行、30,000,000 个单元格数据的电子表格文件。
通过测试,Excel 关上这个文件须要期待 34 秒。
葡萄城 GcExcel 读取这份文件的极限性能是 12 秒
GrapeCity Documents for Excel(简称:GcExcel)是一款由王鸿老师参加设计,由西安葡萄城自主研发的基于 Java 和 .NET 平台的服务端高性能表格组件。
应用该组件,零碎无需依赖 Office、POI 或第三方应用软件,即可在服务端批量创立、加载、编辑、打印、导入 / 导出 Excel 文档,满足在线文档的前后端数据同步、服务端批量导出与打印,以及类 Excel 报表模板设计和服务端高性能数据处理的业务需要,提供一套欠缺的类 Excel 全栈解决方案。
通过测试,用葡萄城的表格组件 GcExcel 关上这样一份文件,仅需 12 秒。
为了实现与 Excel 近 22 秒的性能差距,葡萄城 GcExcel 都做了哪些性能优化呢?实际上,在推出自主研发的表格组件之前,葡萄城便曾经对 Excel 文档的格局、款式和存储构造进行了深刻的钻研。
从 Office 2007 开始,Excel 文件就是一个规范的 Zip 文件,对其解压后,找到一个名为“Worksheets”的文件夹,在其中的“sheet1.xml”文件中,寄存了每个 Excel 文件单元格对应的地位和值。
因而,如何通过更高效的算法取出这些地位和值,便是葡萄城的重点优化方向。
对于一段未经优化的 C# 代码而言,把每个单元格的值读出来,寄存在一个 List 中,须要 27 秒。在这里,仅仅将代码中的 object 改为 double,就能够让其在 20 秒实现。
葡萄城表格组件的性能优化实际
一、缩小垃圾回收
由 27 秒变为 20 秒的差距,便是垃圾回收带来的影响。
在 List 中有太多的 object 对象,这消耗了大量的垃圾回收工夫,只管它没有被回收掉,但因为它们是 object,所以在垃圾回收的过程中,须要一直的检测它们是否能够回收,将 object 改为 double,垃圾回收的工夫便能够忽略不计。
GcExcel 如何克服垃圾回收的影响?
- 打消单元格概念,用 double 存储数字、文本、布尔和谬误类型。
- 行存储改成列存储。利用 C# 的泛型,让字典中存储值类型数据。
二、共享存储及款式压缩
所谓共享存储,就是把整个软件中独特的对象只生成一份,放在一个全局的中央,每个对象用一个数字做 ID,其它中央只存这个 ID。
以上面的文本为例,所有的文本集中存储在一个表中,每个文本有一个惟一的 ID,单元格中只存储这个 ID。
共享存储对升高内存和晋升性能有非常明显的作用:
- 升高内存耗费。对一个数据量很大的软件,会有很多数据都是反复的,比方电子表格中,如果文本的数量很大,那么反复率就十分高,把这些文本集中存储,雷同的只存一份,你会发现,不同的文本数量其实很少,这会极大升高内存耗费。
- 晋升性能。以对字符串做查找、替换为例,如果没有共享集中存储,必须要扫描所有的单元,对每一个单元格文本都做一次比拟操作。但有了共享存储,就只须要查找“字典”就能够了;在字符串比拟时,只须要比拟数字是否相等就能够了;在排序等操作中,只需先把表中的字符串建设一个索引,排好序,前面须要时利用这个索引就能够了。
通过共享存储,GcExcel 曾经把内存的耗费升高了很多,但仍能够进一步优化,便是利用款式压缩。
如上图所示,保留这张样式表不须要在每个单元格中存储一个数字,而是通过建设一个索引表,表的一栏记录一个区域(一个矩形),另一栏记录这个区域对应的款式的 ID。
通过这样的形式,便能够把款式的存储空间再度升高。极其一点讲,如果整个工作表都是同一种款式,那么这里只须要存储一个矩形和一个数字。
三、充分利用高速缓存
当初的 CPU 都有高速缓存,它能晋升 CPU 解决数据的性能。这个图展现了不同存储介质和 CPU 的关系:越高速的存储介质离 CPU 更近,速度越快、空间更小、价格越贵。
CPU 在读取数据的时候,先从最近的缓存中读,只有没命中,才从下一级缓存中读。因而,晋升缓存命中率对改善性能意义重大。
同时,当数据从较慢的存储介质往较快的存储介质复制时,不是顺次进行,而是一块一块的复制,也就是说,当拜访内存中某一个数据时,它四周相邻的数据也一起读入了离 CPU 最近的高速缓存。因而,如果下一个时刻就读相邻的数据,便能够间接在缓存中找到,读取速度就会十分快。
晓得了高速缓存的原理,如何编写缓存敌对的代码?
· 在组件设计的时候,抉择什么样的数据结构得留神,比方数组和字典,受缓存的影响可能不一样。
· 在拜访数据的时候,要留神数据的存储形式。
当然,除了上述三个优化办法,葡萄城还有更多优化实际。如创立 Cache、应用基于汇合的操作运算、利用 SIMD 计算大量数据等。
以上就是王鸿老师行将分享的局部内容,目前,这些高性能的表格技术均曾经实现落地。
表格技术落地:SpreadJS 和 GcExcel
在前端,纯前端表格控件 SpreadJS 可针对 Excel、Grid 数据进行在线编辑、在线填报、公式计算,以及各类 Excel 的模板设计;在后端,服务端表格组件 GcExcel 可疾速批量解决 Excel 文档,提供高度基于 Excel 的文档对象模型,并执行更高效的导出与打印。
最初,欢送大家预约本期葡萄城公开课《葡萄城高性能表格技术优化实际》,与王鸿老师在线探讨,并针对具体业务场景抉择更加适合的优化实际思路。