2020-10-21

前端 BUG 录 – 因数组排序造成的卡顿

前端 BUG 录 – 因 lodashjs debounce 去抖优化造成的 bug
这两个 BUG 其实是同一个 BUG,怎么说呢?两个都没错,错就错在同时使用了。

因为我没处理边界,导致我会给一个大数组排序,造成了卡顿。然后卡顿造成了节流时间成为了笑话。

提问

因为这个 BUG 其实有好几个限定条件才会触发,所以我先来提几个问题

  1. 5000乱序的数据,排序需要多少时间? Array.prototype.sort
  2. 5000有序的数据,排序需要多少时间? Array.prototype.sort
  3. 对于有序数据,什么样的算法合适?
  4. 对于无序数据,什么样的算法合适?
  5. Array.prototype.sort 使用的是什么算法?

这些灵魂拷问,你有答案吗?

我当前的这个场景是分页拉取数据展示的时候要有序

如果你有答案,那可以知道,sort 对于我的这个场景不是很适用,插入排序应该是最优的选择

Array.prototype.sort 测试

地址:https://www.lilnong.top/static/html/user-session-list-virtual-insertsort-log-2.html

image.png

Array.prototype.shuffle = function() {
  let array = this;
  let len = array.length;
  for (let i = len - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}
vm.list.shuffle();

console.time('a')
vm.list.sort((n,m)=>n.id-m.id);
console.timeEnd('a')

console.time('b')
vm.list.sort((n,m)=>n.id-m.id);
console.timeEnd('b')

console.time('c')
vm.list.sort((n,m)=>n.id-m.id);
console.timeEnd('c')

我遇到的问题&解决方案

Array.prototype.sort 代码有过升级

其实在新的浏览器中跑,我的方案也是能过去了,耗时也就 10ms 以下。
但是因为我们是 pc客户端,需要兼容 xp 系统,所以 chrome 的版本极低(40多)

新版本使用的其实是 timsort,timsort 是工业级算法,其混用插入排序与归并排序,二分搜索等算法,亮点是充分利用待排序数据可能部分有序的事实,并且依据待排序数据内容动态改变排序策略——选择性进行归并以及 galloping。什么是Timsort排序方法?

所以这里我们可以把 sort 改成 timsort。
image.png

只需要一次插入排序

https://www.lilnong.top/static/html/user-session-list-virtual-insertsort-log-2.html

因为我的数据是有序的,所以插入排序可以更快。
image.png

我依赖 lodash 的 _.sortedIndexBy 来实现,因为还有置顶规则,所以提供了一个计算权重的方法

image.png

微信公众号:前端linong

欢迎大家关注我的公众号。有疑问也可以加我的微信前端交流群。
clipboard.png

https://segmentfault.com/a/1190000037455206

发表回复

Your email address will not be published. Required fields are marked *