Skip to content

Peak memory use optimizations. #199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 10, 2020

Conversation

dylansturg
Copy link
Contributor

Reduce peak memory usage of swift-format by discarding collections once they are no longer needed.

  • Remove Token arrays from beforeMap and afterMap while processing the associated token.
  • Empty preVisitedExprs after visitation finishes for the root expression of the tree.

beforeMap and afterMap

By the end of a file, these maps can accumulate a meaningful number of tokens such that they significantly impact the peak memory usage.

This admittedly replaces a O(1) lookup operation with a O(N) lookup-and-remove operation, by replacing subscript with removeValue(forKey:). In my testing, I found that this had no impact on the runtime. My hypothesis is that removing from these dictionaries keeps them small enough that O(N) runtime isn't a problem.

preVisitedExprs

This set previously contained ExprSyntax objects and was maintained for the entire file. Once the visitor has finished with all children of the node that initiated inserting the contextual breaks, it will never visit any of the children again. This set can be emptied at that point to keep it from growing until the visitor finishes with the whole file.

Results

The runtime is unchanged, but this reduces peak memory usage especially for large files.

  • Large file (30k LOC): 108.3 MB peak to 72.1 MB peak
  • Medium file (10k LOC) : 35.9 MB peak to 24.4 MB peak
  • swift-protobuf library (many small files): 77.6 MB peak to 75.6 MB peak

Copy link
Member

@allevato allevato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Reduce peak memory usage of swift-format by discarding collections once they are no longer needed.
- Remove `Token` arrays from `beforeMap` and `afterMap` while processing the associated token.
- Empty `preVisitedExprs` after visitation finishes for the root expression of the tree.

By the end of a file, these maps can accumulate a meaningful number of tokens such that they significantly impact the peak memory usage.

This admittedly replaces a O(1) lookup operation with a O(N) lookup-and-remove operation, by replacing `subscript` with `removeValue(forKey:)`. In my testing, I found that this had no impact on the runtime. My hypothesis is that removing from these dictionaries keeps them small enough that O(N) runtime isn't a problem.

This set previously contained `ExprSyntax` objects and was maintained for the entire file. Once the visitor has finished with all children of the node that initiated inserting the contextual breaks, it will never visit any of the children again. This set can be emptied at that point to keep it from growing until the visitor finishes with the whole file.

The runtime is unchanged, but this reduces peak memory usage especially for large files.

- Large file (30k LOC): 108.3 MB peak to 72.1 MB peak
- Medium file (10k LOC) : 35.9 MB peak to 24.4 MB peak
- swift-protobuf library (many small files): 77.6 MB peak to 75.6 MB peak
@dylansturg dylansturg force-pushed the less_memory_makes_me_happy branch from 7ecb041 to 4c8587f Compare June 9, 2020 23:43
@allevato allevato merged commit 0cb597e into swiftlang:master Jun 10, 2020
@dylansturg dylansturg deleted the less_memory_makes_me_happy branch August 14, 2020 19:41
aaditya-chandrasekhar pushed a commit to val-verde/swift-format that referenced this pull request May 20, 2021
aaditya-chandrasekhar pushed a commit to val-verde/swift-format that referenced this pull request May 20, 2021
aaditya-chandrasekhar pushed a commit to val-verde/swift-format that referenced this pull request May 20, 2021
Verifies that generated `all.css` contains the `:root` string on CI. It doesn't do any actual CSS parsing to verify its full validity, only does a simple `grep` check, but I hope this will be enough to prevent issues like swiftlang#198 in the future.

* Test that `all.css` contains a valid CSS selector

* Update `CHANGELOG.md`

* Install graphviz to avoid warnings on macOS

* Add EndToEndTests subclassing XCTest

* Apply suggestions from code review

Co-authored-by: Mattt <[email protected]>

* Remove stray comment leftover from review

* Set macOS 10.13 as minimum platform target

* Refactor EndToEndTests

Create helper methods on Process and Bundle

* Test whether generated HTML output contains subdirectories

* Add test for CommonMark output

* Add tests for coverage subcommand

* Add tests for diagram subcommand

* Update Changelog entry for swiftlang#199

* Work around unavailability of hasDirectoryPath

* Update Changelog.md

Co-authored-by: Max Desiatov <[email protected]>

* Update Changelog entry for swiftlang#199

Co-authored-by: Mattt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants