Flutter documentation for ChangeNotifier says

ChangeNotifier is optimized for small numbers (one or two) of listeners. It is O(N) for adding and removing listeners and O(N²) for dispatching notifications (where N is the number of listeners).

Is there an alternative class available for use in Flutter if I want to design a model where there will be many number of listeners (e.g. dozens of listeners)?

Ideally, I am looking for something with less than O(N^2) for dispatching notifications where N is number of listeners.


Solution 1: ch271828n

Interestingly, when I look at the latest code/doc, it is optimized now!

It says (2021.01):

It is O(1) for adding listeners and O(N) for removing listeners and dispatching notifications (where N is the number of listeners).

Thus we can happily use it. Yeah!

For why this happens: Looking at the source code

  void notifyListeners() {
    assert(_debugAssertNotDisposed());
    if (_listeners!.isEmpty)
      return;

    final List<_ListenerEntry> localListeners = List<_ListenerEntry>.from(_listeners!);

    for (final _ListenerEntry entry in localListeners) {
      try {
        if (entry.list != null)
          entry.listener();
      } catch (exception, stack) {
        ...
      }
    }
  }

we see it iterate through the listeners and call them.

In the old days, say even flutter 1.21, the source code looks like:

  void notifyListeners() {
    assert(_debugAssertNotDisposed());
    if (_listeners != null) {
      final List<VoidCallback> localListeners = List<VoidCallback>.from(_listeners!);
      for (final VoidCallback listener in localListeners) {
        try {
          if (_listeners!.contains(listener))
            listener();
        } catch (exception, stack) {
          ...
        }
      }
    }
  }

Thus you see, in the old days there is double loop (a for loop + a contains check), and in the new days there is not.