RecyclerView 差异更新(diff)

    React中最神奇的部分莫过于虚拟DOM,以及其高效的Diff算法,为这个框架如此流行的基石。在React中,构建UI界面的思路是由当前状态决定界面。前后两个状态就对应两套界面,然后由React来比较两个界面的区别,这就需要对DOM树进行Diff算法分析。即给定任意两棵树,找到最少的转换步骤。但是标准的的Diff算法复杂度需要O(n^3),这显然无法满足性能要求。要达到每次界面都可以整体刷新界面的目的,势必需要对算法进行优化。这看上去非常有难度,然而Facebook工程师却做到了,他们结合Web界面的特点做出了两个简单的假设,使得Diff算法复杂度直接降低到O(n)。

    android support-library 24.2.0版本提供了一个新的 DiffUtil 类可以计算两个集合之间的差异,并分派适合 RecyclerView.Adapter 使用的更新操作列表。DiffUtil使用的是" Eugene W. Myers's difference"算法。来看看这个算法的有啥优势

该算法为空间优化, 使用 o (n) 空间来查找两个列表之间的加法和移除操作的最小数目。它有 o (n + D^2) 预期的时间性能, 其中 d 是编辑长度。

如果启用了移动检测, 则需要额外的 o (n ^ 2) 时间, 其中 n 是添加和移除项的总数。如果您的列表已按相同的约束 (例如, 为list创建的时间戳) 排序, 则可以禁用移动检测以提高性能。

算法的实际运行时显著取决于列表中的更改数和比较方法的开销。下面是一些平均运行时间, 供参考: (测试列表由随机 uuid 字符串组成, 测试运行在与 m 的连结5X 上)

百项和十个修改: avg: 0.39 毫秒, 中值: 100 ms
百项和百修改: 中位数: ms
百项和百修改不移动: 2.09 毫秒, 中值: 2.06 毫秒
1000项和50修改: avg: 4.67 毫秒, 中值: 4.59 毫秒
1000项和50修改没有移动: avg: 中中值: ms
1000项目和200修改: 27.07 毫秒, 中值: 26.92 毫秒
1000项和200修改不移动: 13.54 毫秒, 中值: 13.36 毫秒
由于实现约束, 列表的最大大小可以是两大。

哈哈,好厉害啊

转载于:https://my.oschina.net/droidwolf/blog/877427

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值