Skip to content

_applyPendingFileChanges is O(known libraries) and does not dedupe events #62760

Description

@davidmorgan

This showed up while digging into a perfetto trace from @mraleph here which shows a surprisingly high amount of time spent in _applyPendingFileChanges.

The trace is captured from opening VSCode on the packages repo and running the pigeon package generator under packages/pigeon: tool/generate.dart.

The number of known libraries in the packages repo is very large because there are ~40 packages and it's not a workspace. So this is one part of what is causing the slowness.

The pigeon generator writes files using file.openWrite which does not buffer and so many "change" events are fired on Linux. (Other OSes have some built-in debouncing going on).

So this can be repro'd in any very large VSCode project by triggering lots of file changes, the pigeon generator example causes something like 140k file events.

// writes.dart
import 'dart:io';
void main(List<String> arguments) async {
  final sink = File('lib/many_changes.dart').openWrite();
  for (var i = 0; i != 50000; ++i) {
    sink.write('\n$i');
  }
}

Then we start to see slowdown here

if (cycleFiles.any(removed.contains)) {

as it iterates over every known library URI calling removed.contains.

So there is potential for improvement here by

  • deduping file events: _applyPendingFileChanges could discard repeated changes to the same path
  • faster "find library cycles that match URIs to remove", e.g. with a Map<Uri, LibraryCycle>.

of course having optimized for the huge/rare case, the really interesting thing will be to see if there is any improvement for common cases :) ... in particular whether faster library cycle removal will help normal use in large or very large projects.

Metadata

Metadata

Assignees

Labels

area-dart-modelFor issues related to conformance to the language spec in the parser, compilers or the CLI analyzer.dart-model-analyzer-packageIssues related to package:analyzer

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions