3

在 Flutter 中有两个功能:

  • findAncestorWidgetOfExactType
  • 依赖InheritedWidgetOfExactType

他们在文档中说:findAncestorWidgetOfExactType相对昂贵(在树的深度为O(N))。

并且dependOnInheritedWidgetOfExactTypeO(1),具有一个小的常数因子。

任何人都可以解释为什么?为什么第一个比另一个贵?

谢谢

4

2 回答 2

4

性能的主要区别不是因为findAncestorWidgetOfExactType()搜索任何 Widget 子类,而dependOnInheritedWidgetOfExactType()仅搜索 InheritedWidget 子类。

dependOnInheritedWidgetOfExactType()成本更低,因为每个小部件(更准确地说,每个元素)都保留了_inheritedWidgets所有祖先 InheritedWidgets 的 Map(在字段中),并按它们的类型进行索引。然后dependOnInheritedWidgetOfExactType()不在小部件的树中搜索,而仅在此地图中搜索。

有用的文章:

“Flutter InheritedWidget 是如何工作的?”

“Widget - State - Context - InheritedWidget”(来自 Didier Boelens,一篇文章的作者也在 flutter.dev 中引用)

于 2020-04-13T15:53:53.600 回答
3

要回答这个问题并理解为什么两种方法在时间复杂度上存在差异,我们首先需要澄清两件事:

1-什么是线性搜索?

线性搜索(称为顺序搜索)是一种用于在列表中查找目标值的算法。它依次检查列表中的每个元素的目标值,直到找到匹配项或搜索完所有元素。

简而言之,O(1) 意味着它需要一个恒定的时间(例如 10 纳秒)。

另一方面,O(N) 意味着它所花费的时间与集合的大小成线性关系,因此两倍大小的集合将花费两倍的时间。您可能不想将一百万个对象放入其中之一。

因此( findAncestorWidgetOfExactType )的文档中的提示

“仅当从这个小部件到所需祖先的距离已知很小且有界时才调用此方法。”

2-每种方法搜索的通用“类型”是什么以及在哪里

  • dependOnInheritedWidgetOfExactType< T 扩展InheritedWidget >
  • findAncestorWidgetOfExactType< T 扩展小部件>

考虑到这些,我们可以回答这个问题.. 那么为什么?

因为 findAncestorWidgetOfExactType 方法在所有小部件树中搜索(因为它们默认都是Widget类型)

这是通过线性搜索小部件树来完成的,因此 => O(N)。

由于Mabsten 的回答,这部分得到了更新

另一方面,dependOnInheritedWidgetOfExactType
搜索不在小部件树中,而是在包含所有祖先InheritedWidgets的每个元素随附的地图中搜索,并按其类型进行索引。

所以'dependOn' -直接- 从这个地图中获取正确的继承小部件,这就是它是 O(1) 的原因。

于 2020-03-29T09:30:58.367 回答