为什么 findAncestorWidgetOfExactType 是 O(N) 而 dependOnInheritedWidgetOfExactType 是 O(1)

Why findAncestorWidgetOfExactType is O(N) and dependOnInheritedWidgetOfExactType is O(1)

在 Flutter 中有两个函数:

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

dependOnInheritedWidgetOfExactTypeO(1) 有一个小常数因子。

谁能解释为什么?为什么第一个比另一个贵?

谢谢

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

1-什么是线性搜索?

Linear search (known as sequential search) is an algorithm for finding a target value within a list. It sequentially checks each element of the list for the target value until a match is found or until all the elements have been searched.

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

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

因此 ( findAncestorWidgetOfExactType )

文档中的提示

"Only call this method if the distance from this widget to the desired ancestor is known to be small and bounded."

2- 什么是通用 'Type' 每个方法搜索和 Where ?

  • dependOnInheritedWidgetOfExactType< T extends InheritedWidget >
  • findAncestorWidgetOfExactType< T extends Widget >

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

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

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

This part is updated thanks to Mabsten answer

另一方面 dependOnInheritedWidgetOfExactType
在小部件树中搜索 Not,而是在包含所有祖先 InheritedWidgets 的每个元素附带的 map 中搜索, 由它们的 类型 索引。

因此 'dependOn' - 直接 - 从该映射中获取正确的继承小部件,这就是 O(1) 的原因。

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

dependOnInheritedWidgetOfExactType() 更便宜,因为每个小部件(更准确地说,每个元素)都保留所有祖先 InheritedWidget 的映射(在字段 _inheritedWidgets 中),按它们的类型索引。然后 dependOnInheritedWidgetOfExactType() 不在小部件的树中搜索,而只在这张地图中搜索。

有用的文章:

"How does Flutter InheritedWidget work?"

"Widget - State - Context - InheritedWidget"(Didier Boelens,flutter.dev 中也引用了一篇文章的作者)