找回密码
 立即注册

QQ登录

只需一步,快速开始

BND
金牌服务用户   /  发表于:2024-4-20 20:38  /   查看:2326  /  回复:32
本帖最后由 Ellia.Duan 于 2024-5-29 09:48 编辑


调研编号:DOCXLS-10431

GcExcel操作IRange.setFormula及IRange.setValue方法,在表格较大时耗时过长,


具体请下载提供的示例代码,执行Test.java文件
image.png991480102.png
这里的一个单元格耗时普遍超过200ms,数据量很大的时候非常慢

dyTest.zip

122.56 KB, 下载次数: 191

示例代码

32 个回复

正序浏览
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-30 10:58:45
33#
BND 发表于 2024-5-30 09:59
按你这边给过来的方案,本地测试,耗时减少很多。

方案的核心可不可以按如下理解?

您的理解正确,在公式中尽量避免A:A,使用有效数据区域。
回复 使用道具 举报
BND
金牌服务用户   /  发表于:2024-5-30 09:59:42
32#
Ellia.Duan 发表于 2024-5-29 18:25
您好,我上传了了一下新的项目,请参考附件

excel文件更新为new_all.xlsx

image.png957340087.png
按你这边给过来的方案,本地测试,耗时减少很多。

方案的核心可不可以按如下理解?

Excel中区域的参数如A:A、B:B、......会被视为A1:A1000000、B1:B1000000、......进行处理。
尽可能将公式中选择区域的参数如A:A、B:B、......替换为A1:A100000、B1:B100000、......
至于后面是100000还是10000或者更小,可视区域数据最大行数决定,只要不小于区域数据最大行数,就不会影响结果。
回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-29 18:25:07
31#
本帖最后由 Ellia.Duan 于 2024-5-29 18:36 编辑

您好,我上传了了一下新的项目,请参考附件
gcexceldemo5.zip (19.35 MB, 下载次数: 36)
回复 使用道具 举报
BND
金牌服务用户   /  发表于:2024-5-29 15:35:26
30#
Ellia.Duan 发表于 2024-5-29 12:23
您好,我们经过调研,发现有一个可以优化的公式,优化后getValue耗时缩短为12秒,如下图所示:

image.png739508666.png
按你说的方式进行了处理,本地测试多次,耗时23~30秒之间,并未有提升。
附上demo《gcexceldemo2.rar》,麻烦看一下。

gcexceldemo2.rar

9.36 MB, 下载次数: 23

回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-29 12:23:27
29#
本帖最后由 Ellia.Duan 于 2024-5-29 16:18 编辑

您好,我们经过调研,发现有一个可以优化的公式,优化后getValue耗时缩短为12秒,如下图所示:

image.png318952025.png

具体优化过程是:
在“总裁办计薪_绩效考核异常_线下数据源”sheet中 在K1单元格输入公式“=A:A&D:D”
然后将您的代码中194行代码

  1. //(column = columnArray[37]).setFormula2("=IFERROR(ROUND(@IF(OR(AND(LEFT(J2,7)=N2,--RIGHT(J2,2)>15),@XLOOKUP(C2&N2,总裁办计薪_绩效考核异常_线下数据源!A:A&总裁办计薪_绩效考核异常_线下数据源!D:D,总裁办计薪_绩效考核异常_线下数据源!C:C,"")="否"),W2,XLOOKUP(C2&N2,总办计薪绩效金额0412!B:B&总办计薪绩效金额0412!E:E,总办计薪绩效金额0412!P:P))/O2*P2,2),0)");
复制代码


替换为
  1. (column = columnArray[37]).setFormula2("=IFERROR(ROUND(@IF(OR(AND(LEFT(J2,7)=N2,--RIGHT(J2,2)>15),@XLOOKUP(C2&N2,总裁办计薪_绩效考核异常_线下数据源!K:K,总裁办计薪_绩效考核异常_线下数据源!C:C,"")="否"),W2,XLOOKUP(C2&N2,总办计薪绩效金额0412!B:B&总办计薪绩效金额0412!E:E,总办计薪绩效金额0412!P:P))/O2*P2,2),0)");
复制代码
替换的内容是
image.png184718321.png

这样子做的结果是:
每次IFERROR计算,将不会重新对XLOOKUP中数百万行数据重新计算,新增的K列相当于是一个缓存。
关于类似公式,也可以这样子处理
关于其他优化,我们还在调研中,有结论继续会发给您。


回复 使用道具 举报
BND
金牌服务用户   /  发表于:2024-5-29 09:52:34
28#
本帖最后由 BND 于 2024-5-29 09:55 编辑
Ellia.Duan 发表于 2024-5-29 09:43
您好,解压您的文件,运行时长如下图所示

观察到项目中GcExcel不是最新版本,所以做了下新版本的测试,7 ...
这个事情挺急的,麻烦尽快处理。

我们所有环境已经上线7.1.2版本,我之前提到的实际业务场景给出的整个过程的耗时也是基于该版本。

只是本地demo的没有调整gcexcel版本。
回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-29 09:43:16
27#
本帖最后由 Ellia.Duan 于 2024-5-29 09:44 编辑

您好,解压您的文件,运行时长如下图所示
e3a07a051bcb646baa92827e96a65dc.png937641601.png
观察到项目中GcExcel不是最新版本,所以做了下新版本的测试,7.1.2版本 getValue用时28秒, 6.0.6版本getValue用时117秒。
所以新版本会快很多。

3e9ce15f48c6a9997db90c387d09181.png479107970.png
同时,我在Excel中打开生成的xlsx文件,如下动图所示,大概用时23秒
打开时间.gif



我将在7.1.2版本上继续为您调研,是否还有优化空间。

回复 使用道具 举报
BND
金牌服务用户   /  发表于:2024-5-28 21:46:56
26#
Ellia.Duan 发表于 2024-5-28 14:48
您好,
首先回答您关于开启迭代运算后,setFormula 耗时较长的原因:

image.png958941345.png
这是基本按实际场景的数据规模与公式,本地测试得到的耗时情况。
麻烦支持,提供优化方案。

demo详见《gcexceldemo2.rar》附件

gcexceldemo2.rar

7.34 MB, 下载次数: 28

回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-28 14:48:45
25#
您好,
首先回答您关于开启迭代运算后,setFormula 耗时较长的原因:

迭代运算主要是为了解决循环引用的问题,开启迭代运算,setFormula时,会有一部分公式计算。再此过程中,因为有公式计算,所以getValue耗时较短。
而关闭迭代运算,设置延迟标脏,此时setFormula ,对此部分内容不标脏,即不计算,等到设置延迟标脏结束,此时getValue ,公式参与计算。

根据您提供的测试数据:
方案一、三 setFormula 、getValue 总体耗时大致相同 ,说明此耗时是当前文件公式计算的整个耗时,已经排除了重复计算的时间。
是目前GcExcel可以提供最优性能方案了。

对于您提供的demo ,方案三总体耗时1.8s ,目前来看是正常的。
最后,由于没有您复杂的报表,所以想了解下,此报表在Excel中打开需要多久,或者公式计算有多久?




回复 使用道具 举报
1234下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部