找回密码
 立即注册

QQ登录

只需一步,快速开始

Andy.C

注册会员

14

主题

52

帖子

162

积分

注册会员

积分
162
Andy.C
注册会员   /  发表于:2023-11-16 14:51  /   查看:2960  /  回复:20
1金币
本帖最后由 Richard.Huang 于 2023-12-28 16:41 编辑

产品:GcExcel
版本:V4.2

代码如下:
  1. IWorkbook wk = new Workbook();
  2. wk.Options.Formulas.EnableIterativeCalculation = false;
  3. var json = File.ReadAllText("d:\\temp\\6fed6435-b289-45ce-aa32-57f42b535d4a.ssjson");
  4. wk.FromJson(json);


  5. Stopwatch stopwatch = new Stopwatch();
  6. for (int i = 0; i < 100; i++) {
  7.     stopwatch.Start(); // 开始计时
  8.     wk.DeferUpdateDirtyState = true;
  9.     wk.Worksheets["去化及回款规则"].Range["L11"].Value = 0.33;
  10.     // 执行需要监控性能的代码块
  11.     wk.DeferUpdateDirtyState = false;
  12.     Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed}");
  13.     stopwatch.Reset(); // 停止计时
  14. }
复制代码
越往后的写何解入性能越差,何解?

6fed6435-b289-45ce-aa32-57f42b535d4a.zip

10.56 MB, 阅读权限: 150, 下载次数: 2

20 个回复

正序浏览
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-11-21 18:02:04
20#

嗯,你们的使用场景我也有了解,因为此前应该有和你们会议沟通过。
还是如上所说EnableCalculation如果只是在循环中设置的话,基本没有什么效果。当然这个可能是你们具体的场景需要。

我私信给你联系方式了,你可以加我微信沟通。这个帖子我就先结帖了
回复 使用道具 举报
Andy.C
注册会员   /  发表于:2023-11-21 11:30:51
19#
Richard.Ma 发表于 2023-11-21 11:10
你看一下我13楼发的代码,EnableCalculation是放在循环外面的,目的是不让计算引擎重复去进行公式计算, ...

你可以认为我们是建立的一个持久的公用的workbook,多个人会对这个workbook进行保存值操作。
而不是一个请求创建一个workbook,保存完值就销毁了。下次再重复这个


回复 使用道具 举报
Andy.C
注册会员   /  发表于:2023-11-21 11:19:59
18#
Richard.Ma 发表于 2023-11-21 11:10
你看一下我13楼发的代码,EnableCalculation是放在循环外面的,目的是不让计算引擎重复去进行公式计算, ...

1、这个测试的目的是测试多次保存一个值的情况,如果是一次保存多个值,EnableCalculation会在写值前和写值后。
2、这个验证是为了回答你说使用EnableCalculation和DeferUpdateDirtyState  总体性能是一样的问题。验证的结果是实际差距比较大
3、是否能即时沟通一下,我没办法发私信,是否可以私信个联系方式给我,我们电话沟通一下
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-11-21 11:10:00
17#

你看一下我13楼发的代码,EnableCalculation是放在循环外面的,目的是不让计算引擎重复去进行公式计算,循环结束在开启计算引擎后,在需要获取值的时候,只会计算一次

放在循环里面的话,理论上不会有任何的优化效果,因为该算多少次还是算了多少次。



回复 使用道具 举报
Andy.C
注册会员   /  发表于:2023-11-20 19:42:06
16#
Richard.Ma 发表于 2023-11-20 18:45
你可以对比一下加上tojson以后,这两种方式最终花费的总的时间再说,肯定是关闭计算引擎再算要快的

Defe ...

1、DeferUpdateDirtyState和EnableCalculation 在同样是写值后读取结果表的性能指标对比
往同一个单元格写值,并workSheet.Tojson().   明显EnableCalculation 要比DeferUpdateDirtyState慢很多


  1. Console.WriteLine("vvvvv=====DeferUpdateDirtyState=====vvvvv");
  2.             Stopwatch stopwatch = new Stopwatch();
  3.             for (int i = 0; i < 10; i++)
  4.             {
  5.                 stopwatch.Start(); // 开始计时
  6.                 wk.DeferUpdateDirtyState = true;
  7.                 wk.Worksheets["去化及回款规则"].Range["L11"].Value = 0.33;
  8.                 // 执行需要监控性能的代码块
  9.                 wk.DeferUpdateDirtyState = false;
  10.                 wk.Worksheets["项目概览"].ToJson();
  11.                 Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed}");
  12.                 stopwatch.Reset(); // 停止计时  
  13.             }

  14.             Console.WriteLine("vvvvv=====EnableCalculation======vvvvv");

  15.             for (int i = 0; i < 10; i++)
  16.             {
  17.                 stopwatch.Start(); // 开始计时
  18.                 wk.EnableCalculation = false;
  19.                 wk.Worksheets["去化及回款规则"].Range["L11"].Value = 0.33;
  20.                 // 执行需要监控性能的代码块
  21.                 wk.EnableCalculation = true;
  22.                 wk.Worksheets["项目概览"].ToJson();
  23.                 Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed}");
  24.                 stopwatch.Reset(); // 停止计时  
  25.             }
复制代码
image.png499803466.png


2、不看是否是DeferUpdateDirtyState的问题哈。 但是为什么往同一个单元格写值会越来越慢,计算引擎内部也不能是在相同公式的情况下越来越慢呀。
3、虽然使用EnableCalculation 不会产生越写越慢的问题,但产生了1问题,这也是不可接受的
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-11-20 18:45:07
15#
你可以对比一下加上tojson以后,这两种方式最终花费的总的时间再说,肯定是关闭计算引擎再算要快的

DeferUpdateDirtyState的作用是为了避免关闭计算引擎期间获取的公式单元格值错误。我看到你代码中并没有这个需求,那么完全可以在循环完成后再计算,EnableCalculation设置回true以后,不管是你getValue还是tojson等涉及到获取值的操作时,自然会自动计算,且避免了循环过程中的重复计算

回到你的问题,如果你是想要提升速度,那么EnableCalculation 就是目前能提供的方式,如果你是想要进一步了解为什么在未关闭计算引擎的时候,循环时,每次计算越来越慢(和DeferUpdateDirtyState无关 ),这个属于计算引擎内部的逻辑,目前不是技术支持的范畴。

另外目前新版本V6和V4的计算引擎变化也比较大,一些老版本的计算错误bug已经被修复,建议使用新版本测试和集成。


回复 使用道具 举报
Andy.C
注册会员   /  发表于:2023-11-20 16:22:19
14#
本帖最后由 Andy.C 于 2023-11-20 16:25 编辑
Richard.Ma 发表于 2023-11-20 16:11
我这边测试的结果如下,

1.首先不存在写入性能越来越差的问题,速度慢的原因是公式计算导致的,

写在循环里的目的是为了测试多次保存会出现什么效果,不是说一次保存多个值。

我们也试过关闭计算引擎的方式,带来的问题是打开结果表会变慢。
按照你们的性能文章上讲,关闭计算引擎会导致所有的单元格dirty,这样就对读取的性能差生影响。
你可以在写完值之后加上 wk.Worksheets["项目概览"].ToJson();  这段代码。   
DeferUpdateDirtyState和EnableCalculation  明显在tojson这里会有比较大的性能差异
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-11-20 16:11:11
13#
image.png408139037.png

我这边测试的结果如下,

1.首先不存在写入性能越来越差的问题,速度慢的原因是公式计算导致的,
2.你在循环里面设不设置DeferUpdateDirtyState是完全没有用的。因为每次设置了DeferUpdateDirtyState = false;照样会重新计算。
即使设置也应该是在循环外的头尾设置才有用
image.png40937499.png

一般来说在批量修改单元格值会反复触发计算的话,推荐在操作前关闭计算引擎,操作完成后再打开就行,效果和你使用DeferUpdateDirtyState 差不多,但是仅会影响计算,不会造成其他影响
image.png373666686.png

回复 使用道具 举报
Andy.C
注册会员   /  发表于:2023-11-20 15:53:12
12#
Richard.Ma 发表于 2023-11-20 15:21
现在的情况是,如果我不加载你发过来的这个ssjson,即使测试10W次,性能也不会有变化

没有公式的情况下肯定没啥问题啦。  主要是在复杂套表下
图中很明显能看到后面的时间比前面的长

image.png376959838.png

回复 使用道具 举报
Andy.C
注册会员   /  发表于:2023-11-20 15:30:36
11#
Richard.Ma 发表于 2023-11-20 15:21
现在的情况是,如果我不加载你发过来的这个ssjson,即使测试10W次,性能也不会有变化

我上传了一个写好的demo,麻烦您再帮忙看下

GcExcelDemo.rar

10.15 MB, 下载次数: 81

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