perf(discovery): reduce per-file allocations in discovery phase#9991
perf(discovery): reduce per-file allocations in discovery phase#9991qoole wants to merge 1 commit into
Conversation
- Replace QString::split('.') with indexOf/lastIndexOf to extract
basename and extension without allocating a QList<QString> per file.
- Use QStringView for the basename and extension slices so the
comparisons against forbiddenFilenames / forbiddenBasenames /
forbiddenExtensions run against zero-copy views into the original
QString rather than allocating new QString copies.
- Replace 5 QTimer::singleShot(0, ...) calls with
QMetaObject::invokeMethod(Qt::QueuedConnection) which achieves the
same deferred invocation without allocating a QTimer on the heap
each time. In a large sync with many directories, this eliminates
thousands of unnecessary heap allocations.
Signed-off-by: Qoole <2862661+qoole@users.noreply.github.com>
d94f294 to
e1cbaca
Compare
|
Hello there, We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 Thank you for contributing to Nextcloud and we hope to hear from you soon! (If you believe you should not receive this message, you can add yourself to the blocklist.) |
Summary
Three micro-optimizations to the discovery hot path that fire once per file/directory in a sync. With large folder trees these allocations add up to noticeable GC and heap churn.
Changes
QString::split('.')allocates aQList<QString>plus copies for each segment, just to recover the basename and extension. Replaced withindexOf/lastIndexOfto find the cut points directly.QStringViewslices into the originalQStringrather than allocating new ownedQStringcopies. The downstream forbidden-filename / forbidden-basename / forbidden-extension comparisons all compare againstQStringView-compatible data, so no copies are needed.QTimer::singleShot(0, ...)call sites in discovery were replaced withQMetaObject::invokeMethod(Qt::QueuedConnection). Both schedule a slot for the next event loop iteration, but the latter does not allocate aQTimerobject on the heap. In a large sync with many directories this eliminates thousands ofQTimerallocations.Behavior is unchanged — same parsing results, same scheduling semantics.
Checklist
AI (if applicable)