Почему findAncestorWidgetOfExactType равно O (N), а зависящий от OnInheritedWidgetOfExactType равен O (1) - PullRequest
0 голосов
/ 29 марта 2020

во флаттере есть две функции:

  • findAncestorWidgetOfExactType
  • зависимостьOnInheritedWidgetOfExactType

в в документах говорится, что: findAncestorWidgetOfExactType относительно дорогой ( O (N) в глубине дерева).

и зависящий от OnInheritedWidgetOfExactType равен O (1) с небольшим постоянным коэффициентом.

Кто-нибудь может объяснить, почему? почему первый стоит дороже другого?

Спасибо

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Основное отличие для исполнений не в том, что findAncestorWidgetOfExactType() ищет какой-либо подкласс Widget, а dependOnInheritedWidgetOfExactType() ищет только подкласс InheritedWidget.

dependOnInheritedWidgetOfExactType() дешевле, потому что каждый виджет ( точнее, каждый элемент) хранит карту (в поле _inheritedWidgets) всех наследуемых виджетов-предков, проиндексированных по их типу. Тогда dependOnInheritedWidgetOfExactType() не выполняет поиск в дереве виджета, а только на этой карте.

Полезные статьи:

"Как работает Flutter InheritedWidget?"

"Виджет - Состояние - Контекст - InheritedWidget" (Дидье Боленс, автор статьи, цитируемый также в flutter.dev)

0 голосов
/ 29 марта 2020

Чтобы ответить на вопрос и понять, почему между этими двумя методами существует разница во времени, сначала нужно уточнить две вещи:

1 - Что такое линейный поиск?

Линейный поиск (известный как последовательный поиск) - это алгоритм поиска целевого значения в списке. Он последовательно проверяет каждый элемент списка на целевое значение до тех пор, пока не будет найдено совпадение или пока не будут найдены все элементы.

И вкратце, O (1) означает, что требуется постоянное время , (например, 10 наносекунд).

с другой стороны, O (N) означает, что это занимает некоторое время, линейное с размером набора, поэтому набор, вдвое превышающий размер, займет вдвое больше времени. Вы, вероятно, не хотите помещать миллион объектов в один из них.

отсюда подсказка в документах (findAncestorWidgetOfExactType)

"Только вызов этот метод, если известно, что расстояние от этого виджета до нужного предка мало и ограничено. "

2 - Что такое Generi c 'Type', который ищет каждый метод, и Где ?

  • зависимостьOnInheritedWidgetOfExactType InheritedWidget >
  • findAncestorWidgetOfExactType Widget

Имея это в виду, мы можем ответить на вопрос .. так почему?

Поскольку метод findAncestorWidgetOfExactType выполняет поиск во всем дереве виджетов (поскольку все они имеют тип Виджет по умолчанию)

, и это выполняется с помощью линейного поиска вверх по дереву виджетов, таким образом, приходит => O (N).

Эта часть обновляется благодаря Мабстен ответ

, с другой стороны, зависимостьOnInheritedWidgetOfExactType
поиск Не в дерево виджетов, но вместо этого в карте , которая поставляется с каждым Элементом, содержащим всех предков InheritedWidgets , проиндексированных по их типу .

Таким образом, «зависящий от» - напрямую - выбирает унаследованный виджет с этой карты, поэтому это O (1).

...