12 月 19 日,2020 中国 .NET 开发者大会在苏州召开。本次会议以“开源、共享、创新”为主题,结合线下、线上实时同步直播的方式,征集了来自知名企业的 40 余位技术大咖,为 50 余万名开发者带来了近 50 场技术讲座和 .NET 应用实践。
葡萄城的表格技术负责人王鸿先生,有幸作为本次大会的演讲嘉宾,向在场的 .NET 开发者分享了葡萄城高性能表格技术调优方面的经验积累。
王鸿,作为葡萄城表格技术的负责人,自 2014 年起,便一直聚焦于企业高性能表格技术领域的研究,为葡萄城设计了全新的表格组件架构,并带领研发团队推出了一款性能在业界领先的电子表格组件 GcExcel, 积累了大量高并发、高可用性表格组件的架构设计经验。
在本次分享中,王鸿从葡萄城研发电子表格组件的背景与初衷出发,详细对比了 Excel 与原生 C# 代码的读取性能差异,并总结了若干针对 prototype 原型进行性能调优的手段,如减少垃圾回收的影响、共享对象提升性能、压缩数据降低内存、充分利用高速缓存等方式。
以下是王鸿老师的主要分享内容:
早在 30 多年前,电子表格就已经作为办公软件中的一个基础功能套件,首次出现在个人电脑中。近些年,随着网络信息化的进一步加强,电子表格的应用越来越广泛和深入。
如今“表格”也已经成为数据的一种重要表现形式,广泛应用于各类桌面软件、应用系统和 SaaS 平台的存储结构、系统构成中。
葡萄城,很早便投入了研发精力,开拓并探索如何将电子表格以组件的方式嵌入到各类系统中。经过近 30 年的研究,葡萄城的表格技术已经实现了在保留用户 Excel 使用习惯的同时,也能基于用户的经验和积累在业务系统中提供高效的数据处理和可视化能力。
电子表格的应用场景一般都较为复杂,开发实现它们会碰到很多技术难点,其中最为典型的便是性能问题。
葡萄城为实现高性能的表格组件,克服了很多性能挑战:如怎样快速打开和保存一个电子表格文件、如何计算海量的公式函数、如何让用户快速完成大量单元格的值和样式设置等。
为了测试 C# 代码对 Excel 文件的读取性能,王鸿老师选取了一个日常生活中很容易碰到的场景:当一个电子表格文件很大的时候(包含 30 列、1,000,000 行、30,000,000 个单元格数据),用 Excel 打开它需要等待 34 秒。
如果用户想要用更短的时间打开这样的大文件时,有没有办法实现呢?答案是有,经过测试,用葡萄城的表格组件 GcExcel 打开这样一份文件,仅需 12 秒。
Excel 文件就是一个标准的 Zip 文件,对其解压后,找到一个名为“Worksheets”的文件夹,在其中的“sheet1.xml”文件中,存放了每个 Excel 文件单元格对应的位置和值。
如何通过更高效的算法取出这些位置和值,便是葡萄城表格技术的优化方向。对于一段未经优化的 C# 代码而言,把每个单元格的值读出来,存放在一个 List 中,需要 27 秒。在这里,我们仅仅将代码中的 object 改为 double,就可以让其在 20 秒完成。
这 7 秒差距,便是由于垃圾回收带来的影响。在 List 中有太多的 object 对象,这耗费了大量的垃圾回收时间,尽管它没有被回收掉,但因为它们是 object,所以在垃圾回收的过程中,需要不断的检测它们是否可以回收,将 object 改为 double,垃圾回收的时间便可以忽略不计。
葡萄城表格技术如何克服垃圾回收的影响?
消除单元格概念。因为单元格的数量太多了,保留这个概念就很难把 object 的数量降得很低。葡萄城把原来在单元格类型里得数据分开处理,把样式剔除出去另外处理,这里只考虑单元格值。电子表格中单元格的值可能有四种类型:数字、文本、布尔和错误,数字在内部都是用 double 类型来表示,布尔和错误也可以用 double 来存储。对于文本,不能用常规方法存储,但我们可以想一个办法,让 double 也可以存文本,这个后面详细讲。总之,用 double 可以存储所有的 Excel 数据,这样我们就可以设计一个简单单元格的数据对象,它是一个结构体,不是 object 。
行存储改成列存储。电子表格行的数量最大为 2 的 20 次方(约 1048576 ),而列的数量最大为 2 的 14 次方(约 16384 ),所以把行存储改成列存储,可以减少对象的数量。利用 C# 的泛型,让字典中存储值类型数据。经过这样一改造,object 的数量会从九千多万下降到一万多,垃圾回收的影响基本忽略不计。
除了上述优化方法,葡萄城的表格技术还有更多优化实践。如创建 Cache 、使用基于集合的操作运算、利用 SIMD 计算大量数据等。
以上就是王鸿老师分享的主要内容,通过一个个示例代码+时间对比,也让大家对葡萄城高性能的表格技术形成了非常深刻的认识。
于此同时,王鸿老师在大会上分享的高性能表格技术,均已经实现落地。在前端,纯前端表格控件 SpreadJS可针对 Excel 、Grid 数据进行在线编辑、计算和展示;在后端,服务端表格组件 GrapeCity Documents for Excel (简称:GcExcel )可批量处理 Excel 文档,执行更高效的导出与打印。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.