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.
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
packagesrepo and running the pigeon package generator underpackages/pigeon:tool/generate.dart.The number of known libraries in the
packagesrepo 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.openWritewhich 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.
Then we start to see slowdown here
sdk/pkg/analyzer/lib/src/dart/analysis/library_context.dart
Line 161 in d7fa1ce
as it iterates over every known library URI calling
removed.contains.So there is potential for improvement here by
_applyPendingFileChangescould discard repeated changes to the same pathMap<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.