【14.2.2】【如何只遍历有值的单元格】(40805)
本帖最后由 Lynn.Dou 于 2022-2-14 14:15 编辑如果有一个行列 1w * 1w 的 sheet,按照 sheet.getRowCount()、sheet.getColumnCount() 的方式去遍历就得执行 1w ^ 2 次,这是一个性能瓶颈的地方。是否有提供什么 api 可以直接遍历有值(或者说非空状态、无 style 且无值和其他属性等)的单元格?
因为从 toJSON 的结果来看,序列化后 sheet.data.dataTable 是只存储了有状态的单元格的,应该是能提供这个能力的?
您好,
目前SJS没有直接遍历”有值/样式单元格“的API,这边已将您的需求记录至产品需求库中,
如果后续有计划添加此功能,会在本贴通知您。 Lynn.Dou 发表于 2022-1-21 17:44
您好,
目前SJS没有直接遍历”有值/样式单元格“的API,这边已将您的需求记录至产品需求库中,
如果后续 ...
那你们序列化时是怎么处理的,sheet.data.dataTable 是通过遍历所有单元格来生成的吗,那遇到我说的 1w * 1w 的时候性能会怎么样? 这要看你遍历的循环中做了什么事情。SpreadJS中比较占用性能的地方是页面的内容绘制。如果是仅仅是取值或者一些无关痛痒的设置,那么性能的损耗相较于页面重绘来说微乎其微的。
并且这样的性能损耗也无法避免,设想一下,就算我们提供了您说的这样的接口,那么这样的接口的内部又该如何实现呢,答案还是遍历。那么这个遍历是我们来做还是你们来做没有任何区别。
最后,1W*1W的假设个人认为是意义不大,这样的假设首先前端在操作上是无法撑住的,估计还没到你要遍历的那一步,浏览器就撑不住了。SpreadJS用canvas画法都无法撑住的话,其他DOM结构的表格就更不用说了。这是目前整个前端的性能瓶颈,这样的数据量说实话是不应该用纯前端进行处理的。让用户通过前端肉眼观察1W*1W的数据,这恐怕也不太符合现实吧。 本帖最后由 nutstore 于 2022-1-25 11:17 编辑
Clark.Pan 发表于 2022-1-24 12:28
这要看你遍历的循环中做了什么事情。SpreadJS中比较占用性能的地方是页面的内容绘制。如果是仅仅是取值或者 ...
并且这样的性能损耗也无法避免,设想一下,就算我们提供了您说的这样的接口,那么这样的接口的内部又该如何实现呢,答案还是遍历。那么这个遍历是我们来做还是你们来做没有任何区别。
有其他答案的,如果一开始就有这个能力,完全可以做到所有后续的 api 都按这个实现。
比如 workbook.fromJSON 这一步开始,从 WorkbookJson 的 sheet.dataTable 里读取时,就可以知道哪些单元格是有值的(或者说有状态的)。然后内部维护一个 map 来记录对应的数据,每次变化时更新下 map 就可以,用空间换性能。
我从调试的结果来看,你们内部应该是有维护这样的 map 的:
理论上你们 toJSON 序列化的时候应该也是用了内部维护的 map,不然遇到大数据的场景性能就会差,这个接口应该是可以直接开放出来的,或者稍微封装下提供一个遍历非空状态单元格的函数。
那sheet.tables这里面的数据最初始是怎么来的呢,还是遍历得来的。
这与用户自己遍历之后把他保存起来没有差异。
并且理论上你们 toJSON 序列化的时候应该也是用了内部维护的 map 这句话也是不对的
sheet.tables是在tojson时候生成的并不是实现维护的,因为tojson是实时的将当前表格上的内容序列化成json,你并不知道在你上次保存后到这次保存期间用户在表格上做了怎样的操作。如果用你说的内部维护一个map,那么用户做所的每一次操作都要去更新这个map。频繁的交互只会导致整个表格性能更差,对于一些快速输入根本无法做出实时的反应。
页:
[1]