swift-syntax icon indicating copy to clipboard operation
swift-syntax copied to clipboard

Performance regressions in latest 509.0.0 releases

Open SimplyDanny opened this issue 2 years ago • 16 comments

This is not a bug. I just want to inform you about performance regressions we noticed while integrating the two latest 509.0.0 releases of SwiftSyntax into SwiftLint.

In numbers, we see a slowdown of 2% - 3% upgrading from 509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-07-09-a to 509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-08-07-a and another 2% - 3% drop when moving to 509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-08-28-a.

That's probably something you might be interested in.

SimplyDanny avatar Sep 05 '23 19:09 SimplyDanny

Tracked in Apple’s issue tracker as rdar://115001578

ahoppen avatar Sep 05 '23 19:09 ahoppen

Thanks for reporting this. That’s valuable information. The 2-3% performance regression when moving from 07-09 to 08-07 is probably not something that’s reasonable to investigate since it includes way too many commits (08-07 was the first one that we tagged of main again instead of release/5.9).

The regression from 08-07 to 08-28 is quite interesting though. Are you able to bisect which PR might have introduced the regression or is there an easy way to replicate the performance measurements so I can run them?

ahoppen avatar Sep 05 '23 21:09 ahoppen

Unfortunately, I'm not able to boil this down to a specific commit. It's also hard to reproduce the results in any case.

I've done a few tests with the swift-parser-cli tool parsing the SwiftSyntax repository itself with the following results:

Tag Runtime Change
2023-07-09-a 488.95ms
2023-08-07-a 520.92ms +6.5%
2023-08-28-a 516.07ms -0.9%
509.0.0 520.59ms +0.8%

As we see, there's actually been no change since 2023-08-07-a. But that's just parsing. SwiftLint uses a bit more of SwiftSyntax' infrastructure on top of parsing. Perhaps the regression happens there. But as said, it's difficult to analyze that.

Are there performance tests in SwiftSyntax running regularly or even on every PR build?

SimplyDanny avatar Sep 14 '23 20:09 SimplyDanny

As we see, there's actually been no change since 2023-08-07-a. But that's just parsing. SwiftLint uses a bit more of SwiftSyntax' infrastructure on top of parsing. Perhaps the regression happens there. But as said, it's difficult to analyze that.

Are there performance tests in SwiftSyntax running regularly or even on every PR build?

We gather performance measurements when running SwiftParser as part of the SourceKit Stress Tester and I’m monitoring these changes. I also did ad-hoc performance measurements of swift-format for PRs that seemed like they could be risky but haven’t been monitoring that performance continuously.

I was thinking to set up some kind of performance monitoring and would be interested in using SwiftLint as a benchmark if there’s a stable way to get the performance numbers.

ahoppen avatar Sep 14 '23 21:09 ahoppen

Sorry for the late reply. I've totally missed this thread. I come back to this now that we were about to upgrade to SwiftSyntax 510.0.0, but another performance regression of 9% - 13% is holding us back at the moment. Please see the PR for the update. Is there any obvious reason for the performance decrease, @ahoppen?

I was thinking to set up some kind of performance monitoring and would be interested in using SwiftLint as a benchmark if there’s a stable way to get the performance numbers.

Performance in PRs in SwiftLint is measured on dedicated real machines (no VMs) as follows:

  • Two binaries are built with Bazel from both main and the branch that's requested to be merged into main.
  • Both are run on a set of open source Swift repositories by enabling all rules available or only the ones that got changed.

Due to the use of non-virtual machines, the benchmark results are quite reliable.

Most of the rules are meanwhile based on SwiftSytax (parsing and visiting). But some still require SourceKit as well.

SimplyDanny avatar Mar 04 '24 19:03 SimplyDanny

Do you have some kind of script/commands that I could use to reproduce the measurements? I would like to bisect this on swift-syntax because there really haven’t been many changes between 509 and 510.

I did just measure parsing performance using our swift-parser-cli performance-test script and that only showed a 1.5% performance decrease between the two releases, which is in a completely different ballpark.

ahoppen avatar Mar 05 '24 00:03 ahoppen

Do you have some kind of script/commands that I could use to reproduce the measurements?

On the PR branch, you can run ./tools/oss-check. It uses Bazel to build. If you'd like to build with Swift Package Manager instead, you may adapt the command accordingly.

SimplyDanny avatar Mar 05 '24 20:03 SimplyDanny

Oh, that’s great, thanks! I wasn’t expecting something that simple. I was able to reproduce the regression locally using the script. I’ll bisect it now, trying to find out what in swift-syntax might have caused it. I’ll post an update once I’ve got more information.

ahoppen avatar Mar 05 '24 22:03 ahoppen

I think I have found the culprit: https://github.com/apple/swift-syntax/pull/2038 I’m profiling it now to see if there’s something we can do to mitigate the performance impact of that PR.

ahoppen avatar Mar 07 '24 19:03 ahoppen

I knelt down into SyntaxVisitor yesterday and was able to optimize it quite a bit. Instead of a ~10% performance regression, I am seeing a ~10% performance improvement now when building SwiftLint with swift-syntax from https://github.com/apple/swift-syntax/pull/2537. More details are in the PR.

@SimplyDanny Would it be possible for you to test SwiftLint’s performance with that branch, just to double-check that my measurements are correct and that there isn’t another regression hiding somewhere?

I can’t make any statements on whether we can or will include the 510 release series of swift-syntax. Changing memory management is always risky and we need to assess the risk here.

ahoppen avatar Mar 08 '24 18:03 ahoppen

I checked your branch in the same PR and indeed see an impressive performance improvement of 5% - 25% depending on the linted repository compared to 509. Well done! 🎉

SimplyDanny avatar Mar 08 '24 20:03 SimplyDanny

Wohoo. That’s great. 🏎️

We deemed the risk of taking this change into a patch release for the 510 series too big because it’s modifying the memory management in a non-trivial way and it’ll thus be available in the 600 release series aligned with Swift 6.

ahoppen avatar Mar 09 '24 01:03 ahoppen

We deemed the risk of taking this change into a patch release for the 510 series too big ...

As a side note: Apart from the performance improvements, all tests passed and no crashes appeared while scanning several open source repositories.

Any chance this change can be part of a beta version on the 600 line already?

SimplyDanny avatar Mar 09 '24 10:03 SimplyDanny

Here we go: https://github.com/apple/swift-syntax/releases/tag/600.0.0-prerelease-2024-03-11

ahoppen avatar Mar 11 '24 23:03 ahoppen

Here we go: https://github.com/apple/swift-syntax/releases/tag/600.0.0-prerelease-2024-03-11

This does not yet comprise the memory improvements, does it?

SimplyDanny avatar Mar 16 '24 13:03 SimplyDanny

Oh, no, it doesn’t. I just thought the same yesterday when I saw that my PR isn’t merged yet. I’ll try to create prerelease tags weekly now, so it should be in one pretty soon.

ahoppen avatar Mar 16 '24 13:03 ahoppen

It took a while to get a new prerelease out because we want prereleases to build without warnings and I had to do a few fixes in that area. Anyway, 600.0.0-prerelease-2024-04-02 is out now and should contain the improved SyntaxVisitor performance.

ahoppen avatar Apr 02 '24 22:04 ahoppen

Just to report something pleasant here as well again ... 😅

With the jump from 600.0.0-prerelease-2024-04-02 to 600.0.0-prerelease-2024-07-24, SwiftLint saw another performance win of ~10%. Combined, that means the latest release 0.56.1 is up to 30% faster than it would be with the 510.0.2 release (just tested by only altering the SwiftSyntax dependency).

That's impressive and worth a praise in the release notes! Well done, @ahoppen and contributors. 🎉

SimplyDanny avatar Aug 11 '24 19:08 SimplyDanny

A lot of the latest performance work was by @rintaro, probably from https://github.com/swiftlang/swift-syntax/pull/2726. @rintaro Do you want to add that to the release notes?

ahoppen avatar Aug 12 '24 18:08 ahoppen