Skip to content

Low-hanging fruits in ktfmt performance #619

Open

Description

@qwwdfsad

Hey, while we are waiting for #616, it would be nice to get accustomed to the code base and contribution policy, send a few patches, and see how it goes in general. Improving performance without significant architectural changes seems to be a nice place to start!

So far, things I've found that can be done relatively easily:

  • Reuse Parser.parse result if code wasn't changed between formatting steps. The duct-taped version of this change yields ~20-25% of raw throughput. Duplicate of Four calls to Parser.parse cause performance issues #552
  • Parser.parse visits KtFile in search for parsing errors, basically parsing it two times in a row. ~10-15% when commented out (which is not an option for a fix, but an approximation), probably a much less straightforward fix though
  • Avoid redundant allocations where appropriate -- mostly comes from eager materialization of PsiElement.text here and there
  • Avoid substringing every line four times in getMultilineTrimmedStringList (because of lines()). Less generally-applicable, helps a lot for large files with trimIndent/trimMargin (~25% on kftmt, mostly because of FormatterTest.kt which is exactly this pattern)
  • Avoid all the extra work in MultilineStringFormatter when there are no """ and/or trimIndent/trimMargin. ~10-15%?

Note: performance numbers are from runs on kotlinx.* libraries in sequential mode (with commented out parallelStream), parallel mode is too noisy for measurements.

Would you be okay if I gradually start sending patches for these and add @AbdullinAM as a co-reviewer?

Activity

  1. hick209 commented on May 30, 2026

    @hick209
    Collaborator

    Yes, please!

    Those contributions would be appreciated and indeed it a good way to start getting familiarized

  2. added a commit that references this issue on Jun 1, 2026
  3. qwwdfsad commented on Jun 3, 2026

    @qwwdfsad
    MemberAuthor

    Getting rid of redundant parse is trickier because sortedAndDistinctImports unconditionally appends \n -- meaning it changes the code structure even on perfectly-formatted code.
    The good news are that the performance win will be even bigger because my duct-taped hack hasn't spotted it

  4. added a commit that references this issue on Jun 17, 2026
  5. linked a pull request that will close this issueRefactor build scripts #623on Jun 17, 2026
  6. linked a pull request that will close this issueReuse Parser.parse results #622on Jun 17, 2026
  7. linked a pull request that will close this issueAvoid redundant allocations #620on Jun 17, 2026
  8. qwwdfsad commented on Jul 1, 2026

    @qwwdfsad
    MemberAuthor

    Parsing twice is no longer an issue after #622, the real leftover is getMultilineTrimmedStringList

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions