Skip to content

[Performance Enhancements] Lambda expressions format change & Multi-level exploration logic changes#1535

Merged
bulldozer-bot[bot] merged 14 commits intodevelopfrom
cr/perf
Feb 23, 2026
Merged

[Performance Enhancements] Lambda expressions format change & Multi-level exploration logic changes#1535
bulldozer-bot[bot] merged 14 commits intodevelopfrom
cr/perf

Conversation

@crogoz
Copy link
Contributor

@crogoz crogoz commented Jan 16, 2026

Before this PR

Some repos would take 5 - 9 mins to be formatted. This is because we were exploring both preferBreakingLastInnerLevel & breakNormally for each level, with the branching coefficient capped to 20. The exploration is exponential. See below the Benchmark for the before implementation:

Benchmark                           Mode  Cnt  Score   Error  Units
BenchmarkMultiFiles.runNestedLevel  avgt   10  0.502 ± 0.009   s/op

Benchmark                                     Mode  Cnt  Score   Error  Units
BenchmarkMultiFiles.runNestedLevel           thrpt   10  1.985 ± 0.056  ops/s
BenchmarkMultiFiles.runNestedLevel            avgt   10  0.497 ± 0.007   s/op
BenchmarkMultiFiles.runNestedLevel          sample   45  0.499 ± 0.010   s/op
BenchmarkMultiFiles.runNestedLevel:p0.00    sample       0.484           s/op
BenchmarkMultiFiles.runNestedLevel:p0.50    sample       0.493           s/op
BenchmarkMultiFiles.runNestedLevel:p0.90    sample       0.520           s/op
BenchmarkMultiFiles.runNestedLevel:p0.95    sample       0.552           s/op
BenchmarkMultiFiles.runNestedLevel:p0.99    sample       0.583           s/op
BenchmarkMultiFiles.runNestedLevel:p0.999   sample       0.583           s/op
BenchmarkMultiFiles.runNestedLevel:p0.9999  sample       0.583           s/op
BenchmarkMultiFiles.runNestedLevel:p1.00    sample       0.583           s/op
BenchmarkMultiFiles.runNestedLevel              ss   10  0.513 ± 0.029   s/op

After this PR

Performance dashboards here. Internal excavator runs here

Example of the new diff: here or here

Most of the times we prefer preferBreakingLastInnerLevel in order to keep as compact as possible. I changed the logic that started the exploration top-down (with a branching coefficient capped at 20) to an exploration of the last LAST_LEVELS_TO_EXPLORE levels. For the last LAST_LEVELS_TO_EXPLORE I am exploring both preferBreakingLastInnerLevel & breakNormally and I will pick the formatted text that minimises the number of lines.
In order to keep the formatting as compact as possible, I am defaulting to preferBreakingLastInnerLevel for all the upper levels. If no such formatting was found, then I am falling back to breakNormally.

with LAST_LEVELS_TO_EXPLORE=8

Benchmark                                     Mode  Cnt   Score   Error  Units
BenchmarkMultiFiles.runNestedLevel           thrpt   10  26.514 ± 2.834  ops/s
BenchmarkMultiFiles.runNestedLevel            avgt   10   0.041 ± 0.004   s/op
BenchmarkMultiFiles.runNestedLevel          sample  518   0.039 ± 0.001   s/op
BenchmarkMultiFiles.runNestedLevel:p0.00    sample        0.032           s/op
BenchmarkMultiFiles.runNestedLevel:p0.50    sample        0.037           s/op
BenchmarkMultiFiles.runNestedLevel:p0.90    sample        0.043           s/op
BenchmarkMultiFiles.runNestedLevel:p0.95    sample        0.051           s/op
BenchmarkMultiFiles.runNestedLevel:p0.99    sample        0.088           s/op
BenchmarkMultiFiles.runNestedLevel:p0.999   sample        0.117           s/op
BenchmarkMultiFiles.runNestedLevel:p0.9999  sample        0.117           s/op
BenchmarkMultiFiles.runNestedLevel:p1.00    sample        0.117           s/op
BenchmarkMultiFiles.runNestedLevel              ss   10   0.042 ± 0.003   s/op

Because the number of exploration is substantially decreased, just changing the above setup would end up in some cases looking like here. I've noticed that most of the time the setup was wrong was for lambda expressions.

I changed the logic for lambda expressions (lambda body with no curly braces), to instead of trying to inline as much as possible the inner levels of the lambda body (code here) to defaulting to breakNormally:

  • if the lambda expression fits completely on the same line as the parent, it will be inlined
  • otherwise, the lambda body gets split in multiple lines.

Other things that I tried:

  • with LAST_LEVELS_TO_EXPLORE = 12, noticed some perf regression for some repos.
Benchmark                                     Mode  Cnt  Score   Error  Units
BenchmarkMultiFiles.runNestedLevel           thrpt   10  5.427 ± 0.047  ops/s
BenchmarkMultiFiles.runNestedLevel            avgt   10  0.186 ± 0.005   s/op
BenchmarkMultiFiles.runNestedLevel          sample  110  0.188 ± 0.005   s/op
BenchmarkMultiFiles.runNestedLevel:p0.00    sample       0.180           s/op
BenchmarkMultiFiles.runNestedLevel:p0.50    sample       0.185           s/op
BenchmarkMultiFiles.runNestedLevel:p0.90    sample       0.192           s/op
BenchmarkMultiFiles.runNestedLevel:p0.95    sample       0.206           s/op
BenchmarkMultiFiles.runNestedLevel:p0.99    sample       0.273           s/op
BenchmarkMultiFiles.runNestedLevel:p0.999   sample       0.273           s/op
BenchmarkMultiFiles.runNestedLevel:p0.9999  sample       0.273           s/op
BenchmarkMultiFiles.runNestedLevel:p1.00    sample       0.273           s/op
BenchmarkMultiFiles.runNestedLevel              ss   10  0.197 ± 0.041   s/op

==COMMIT_MSG==
Improve perf by inspecting both breaking & not-breaking for the LAST_LEVELS_TO_EXPLORE levels
==COMMIT_MSG==

  • with LAST_LEVELS_TO_EXPLORE = 7, however the formatting would regress in some cases (internal link here). Setting level = 12 fixed the issue.
Benchmark                                     Mode  Cnt   Score   Error  Units
BenchmarkMultiFiles.runNestedLevel           thrpt   10  35.640 ± 2.585  ops/s
BenchmarkMultiFiles.runNestedLevel            avgt   10   0.029 ± 0.002   s/op
BenchmarkMultiFiles.runNestedLevel          sample  705   0.029 ± 0.001   s/op
BenchmarkMultiFiles.runNestedLevel:p0.00    sample        0.024           s/op
BenchmarkMultiFiles.runNestedLevel:p0.50    sample        0.028           s/op
BenchmarkMultiFiles.runNestedLevel:p0.90    sample        0.032           s/op
BenchmarkMultiFiles.runNestedLevel:p0.95    sample        0.035           s/op
BenchmarkMultiFiles.runNestedLevel:p0.99    sample        0.046           s/op
BenchmarkMultiFiles.runNestedLevel:p0.999   sample        0.089           s/op
BenchmarkMultiFiles.runNestedLevel:p0.9999  sample        0.089           s/op
BenchmarkMultiFiles.runNestedLevel:p1.00    sample        0.089           s/op
BenchmarkMultiFiles.runNestedLevel              ss   10   0.029 ± 0.004   s/op
  • Swapping the usage of fj.Set to HashSet. Pjf is trying to compute the line breaks and inserting into a fj.data.Set balancing the sorted set via comparisons. I tried swapping the fj.Set to using a normal HashSet, however this ended up being (more than 10x) slower. This is because the State is immutable and every time we create a new State, we need to copy & edit each Set field, which is much more optimal to do with the fj library than using a normal HashSet.
    See image below from the jfr.
image (1)

Possible downsides?

@changelog-app
Copy link

changelog-app bot commented Jan 16, 2026

Generate changelog in changelog/@unreleased

Type (Select exactly one)

  • Feature (Adding new functionality)
  • Improvement (Improving existing functionality)
  • Fix (Fixing an issue with existing functionality)
  • Break (Creating a new major version by breaking public APIs)
  • Deprecation (Removing functionality in a non-breaking way)
  • Migration (Automatically moving data/functionality to a new system)

Description

[Performance Enhancements] Lambda expressions format change & Multi-level exploration logic changes

Check the box to generate changelog(s)

  • Generate changelog entry

CRogers
CRogers previously approved these changes Jan 19, 2026
Copy link
Contributor

@CRogers CRogers left a comment

Choose a reason for hiding this comment

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

Approved for RC

@policy-bot policy-bot bot dismissed CRogers’s stale review January 19, 2026 10:27

Invalidated by push of b3de33c

@CRogers
Copy link
Contributor

CRogers commented Feb 3, 2026

👍

@crogoz crogoz force-pushed the cr/perf branch 2 times, most recently from 8f76341 to 8761f21 Compare February 3, 2026 13:35
@FinlayRJW
Copy link
Contributor

👍

relative symlink?

comment

sptless

comments
@crogoz crogoz changed the title [WIP] use maxDepth to explore both breaking & not breaking Improve perf by inspecting both breaking & not-breaking for the LAST_LEVELS_TO_EXPLORE levels Feb 3, 2026
@CRogers
Copy link
Contributor

CRogers commented Feb 13, 2026

👍

svc-autorelease and others added 2 commits February 13, 2026 14:22
right comment

comment
kelvinou01
kelvinou01 previously approved these changes Feb 17, 2026
Copy link
Contributor

@kelvinou01 kelvinou01 left a comment

Choose a reason for hiding this comment

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

for rc

@policy-bot policy-bot bot dismissed kelvinou01’s stale review February 17, 2026 17:50

Invalidated by push of de3b8eb

@crogoz crogoz changed the title Improve perf by inspecting both breaking & not-breaking for the LAST_LEVELS_TO_EXPLORE levels [Performance Enhancements] Lambda expressions format change & Multi-level exploration logic changes Feb 19, 2026
@changelog-app
Copy link

changelog-app bot commented Feb 19, 2026

Successfully generated changelog entry!

Need to regenerate?

Simply interact with the changelog bot comment again to regenerate these entries.


📋Changelog Preview

💡 Improvements

  • [Performance Enhancements] Lambda expressions format change & Multi-level exploration logic changes (#1535)

@crogoz crogoz marked this pull request as ready for review February 19, 2026 15:15
@CRogers
Copy link
Contributor

CRogers commented Feb 23, 2026

👍

@bulldozer-bot bulldozer-bot bot merged commit 32f3b92 into develop Feb 23, 2026
7 checks passed
@bulldozer-bot bulldozer-bot bot deleted the cr/perf branch February 23, 2026 15:22
@autorelease3
Copy link

autorelease3 bot commented Feb 23, 2026

Released 2.89.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants