找回密码
 立即注册

QQ登录

只需一步,快速开始

Andy.C
注册会员   /  发表于:2024-4-22 15:54:04
11#
本帖最后由 Andy.C 于 2024-4-22 15:55 编辑
BND 发表于 2024-4-22 15:35
使用我查到的方案有很大提升。

我的理解是这两个方案没有本质不同,核心都是在写数据时,关闭公式计算 ...

关闭计算引擎和延迟标脏是不一样的功能。 关闭计算引擎会导致全表重算,延迟标脏则不会。
如果说表单计算逻辑还好,全表计算也很快,但如果表单计算逻辑复杂一点,全表计算就会很慢~
所以最好的方式就是

workbook.setDeferUpdateDirtyState(true);
setValue();
workbook.setDeferUpdateDirtyState(false);


只用这一种方式,不要两种一起用
回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-4-22 18:02:22
12#
Andy.C 发表于 2024-4-22 15:54
关闭计算引擎和延迟标脏是不一样的功能。 关闭计算引擎会导致全表重算,延迟标脏则不会。
如果说表单计 ...

回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-4-29 14:25:49
13#
您好,注意到您长时间未回复,本贴就先结贴啦,有如果还有问题,可以追贴询问。
回复 使用道具 举报
BND
高级会员   /  发表于:2024-5-23 22:32:18
14#
本帖最后由 BND 于 2024-5-23 22:33 编辑
Ellia.Duan 发表于 2024-4-29 14:25
您好,注意到您长时间未回复,本贴就先结贴啦,有如果还有问题,可以追贴询问。

// 方式1: 禁用公式引擎 Start ......
workbook.setEnableCalculation(false);
setFormulas(columns);
workbook.setEnableCalculation(true);
long c = System.currentTimeMillis();
workbook.dirty();
workbook.calculate();
System.out.println("calculate time = " + (System.currentTimeMillis() - c));
// 方式1: 禁用公式引擎 End .
// 方式2: 设置脏标 Start ......
workbook.setDeferUpdateDirtyState(true);
setFormulas(columns);
workbook.setDeferUpdateDirtyState(false);
// 方式2: 设置脏标 End .


使用以上两种方案,在加载大量数据与运算公式时,性能很低,远不能满足业务要求。Excel模板插入80列以上的Table,其中60多列设置Excel公式进行运算,公式引用来自20多个页签的数据,页签数据在1000行~100000行不等。截取极小部分数据与公式,实际测试中,也并非之前讨论的方式2的性能一定高于方式1,甚至出现方式2的性能远低于方式1。
详见如下案例:
方式1的测试案例:
image.png270068358.png image.png388349913.png


方式2的测试案例:
image.png968820800.png image.png45680846.png


附件《gcexceldemo2.rar》为demo案例,麻烦提供支持,解决性能问题。



gcexceldemo2.rar

582.8 KB, 下载次数: 1099

回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-24 09:54:36
15#
本帖最后由 Ellia.Duan 于 2024-5-24 10:28 编辑

您好,运行您的代码,使用方式一:

image.png881386108.png
使用方式二:
image.png447264098.png

发现方式一的性能要好于性能二 ,我将深入调研下此问题,为您寻找合适的的解决方案。
DOCXLS-10431



回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-24 14:45:25
16#
本帖最后由 Ellia.Duan 于 2024-5-24 15:06 编辑

您好,对于您提供的gcexceldemo2项目,性能慢的最大原因是开启了迭代运算

image.png708571166.png
如果开启了迭代运算,每当设置Value或Formula时,都会导致整个workbook重新计算一次,所以会非常影响性能。
建议您关闭此功能。
同时,关闭迭代运算后,使用方式二,性能可以优化至190毫秒左右
image.png274086608.png


设置关闭计算引擎与延迟标脏不建议混合使用。
您可以参考这篇文章
https://gcdn.grapecity.com.cn/showtopic-143102-1-1.html
关闭计算引擎后,同时setValue与getValue会导致公式计算不正确。对于这种场景,不用关闭计算引擎,而是开启延迟标脏即可。

还有一点就是,关闭计算引擎,打开计算引擎,会导致所有单元格标脏,您的这行代码可有可无
image.png205595091.png
对于延迟标脏来说,只会对其中一部分公式设置延迟标脏,不会进行状态同步。

如果您的工作簿中大部分公式已经计算好,此时新增一部分公式,可以考虑用延迟标脏的方式。否则用关闭计算引擎,会造成之前算好的公式也都参与重计算。
如果您的工作簿中全部都是新增公式,如果存在性能问题,当然可以关闭计算引擎,然后打开计算引擎来提升性能。

回复 使用道具 举报
BND
高级会员   /  发表于:2024-5-24 17:09:28
17#
Ellia.Duan 发表于 2024-5-24 14:45
您好,对于您提供的gcexceldemo2项目,性能慢的最大原因是开启了迭代运算

GcExcel开启/关闭迭代运算的API是什么?
关闭迭代运算会不会造成负面影响,比如某些场景下会干扰公式计算值?
麻烦告知一下。
回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-24 18:22:11
18#
本帖最后由 Ellia.Duan 于 2024-5-24 18:23 编辑
  1. workbook.getOptions().getFormulas().setEnableIterativeCalculation(true);
复制代码
迭代计算是一种功能,用于处理包含循环引用或相互依赖的公式。最简单的例子 A1单元格设置公式“=B1” B1单元格设置公式“=A1”

迭代计算在以下情况下很有用:

1、处理复杂的数学模型:对于涉及复杂数学模型或需要迭代求解的问题,迭代计算可以帮助Excel逐步逼近结果。例如,使用牛顿迭代法计算方程的根。

2、处理时间依赖性和反馈循环:在某些情况下,公式的计算结果可能依赖于之前计算的结果。启用迭代计算可以处理这种时间依赖或反馈循环,确保结果收敛于稳定值。
具体您可以看SpreadJS关于迭代计算的介绍
https://demo.grapecity.com.cn/sp ... -calculation/purejs

也可以参考此文档:
https://gcdn.grapecity.com.cn/showtopic-83637-1-1.html

回复 使用道具 举报
BND
高级会员   /  发表于:2024-5-25 11:48:40
19#
本帖最后由 BND 于 2024-5-25 11:51 编辑
Ellia.Duan 发表于 2024-5-24 14:45
您好,对于您提供的gcexceldemo2项目,性能慢的最大原因是开启了迭代运算

接着说到设置脏标。


workbook.setDeferUpdateDirtyState(true);
setFormulas(columnArray);
workbook.setDeferUpdateDirtyState(false);
getTableValue(table);


以上代码:

启用迭代计算, 设置公式与获取值耗时如下图, 设置公式很耗时。

image.png790356139.png

禁用迭代计算, 设置公式与获取值耗时如下图, 设置公式耗时显著减少,但获取值耗时又增加了。

image.png815976257.png


整体对比下来,禁用迭代计算,性能有提升,但还是不满足业务需求。

附件《gcexceldemo2.rar》为测试demo程序。


我们实际业务场景:Excel模板插入80列以上的Table,加载1000行左右的数据,其中60多列设置Excel公式进行运算,公式引用来自20多个页签的数据,页签数据在1000行~10000行不等。
这个场景,我们业务要求整个计算过程耗时不超过5秒。
实际测得各种方案的耗时:
1、启用/禁用迭代计算,禁用计算引擎,设置公式,开启计算引擎,重算,获取值,整体耗时40~50秒,绝大部分耗时发生在重算
2、启用迭代计算,设置脏标延迟更新,设置公式,关闭脏标延迟更新,获取值,整体耗时40~60分钟,绝大部分耗时发生在设置公式
3、禁用迭代计算,设置脏标延迟更新,设置公式,关闭脏标延迟更新,获取值,整体耗时40~50秒,绝大部分耗时发生在获取值

对比下来,方案3比方案2有很大提升,但跟方案1在耗时上没啥区别,方案3主要耗时就发生获取值这一步。

麻烦支持,提供优化方案。




gcexceldemo2.rar

583.54 KB, 下载次数: 1094

回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2024-5-27 09:30:06
20#
本帖最后由 Ellia.Duan 于 2024-5-27 10:34 编辑

您好,想问下您,您提到了整个计算过程不超过5秒,这个过程为什么要包括获取值的过程?
以及,需要您提供给一个接近您场景的demo 。
image.png141786498.png

我们根据您提供的具体demo ,再具体调研。
DOCXLS-10431

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