scalameta / scalafmt

Code formatter for Scala
http://scalameta.org/scalafmt
Apache License 2.0
1.44k stars 277 forks source link

Some results from profiling #1385

Open jrudolph opened 5 years ago

jrudolph commented 5 years ago

Hi @olafurpg,

I spent a bit of time looking into the performance of scalafmt. See the flame-graph below. I found a few things:

VirtualFile.value

That one was a mystery to me first, it amounts to 8% of total time. I guess the problem here is that Input is used as a key to many of the Maps. For some reason, scalafmt creates VirtualFiles in Scalafmt.format which means that every Map access with the VirtualFile as the key has to hash the complete code again?

TreeOps.getOwners

Removing the recursion seems to help and using a java.util.HashMap instead of a mutable.Map builder.

FormatOps.iter

Basically the same as TreeOps.getOwners.

getSplits

Screenshot from 2019-03-14 11-17-25

That red "Interpreter" frame is getSplits. It seems to mean that the JIT-compiler gave up on that method completely... It may be as you say:

https://github.com/scalameta/scalafmt/blob/8111bb296abf36c8b758a1e43f8ce28b758c03e5/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala#L59

Not sure how the pattern match could be restructured to make it easier for the JIT and for performance.

I'll open a PR for ideas about to improve the first three things. That will probably already improve performance somewhat.

flame-graph

olafurpg commented 5 years ago

@jrudolph Thank you so much for this thorough investigation. I believe the Scalamt codebase is ripe for microoptimizations 👍 The code was written when I was just starting Scala a few years ago and hasn't changed so much since then 😅

I have also investigated several low-hanging opportunities to speed up Scalameta

I personally don't have much time to pursue these ideas but if somebody is interesting in making a contribution I will be happy to provide feedback and review.

kitbellew commented 4 years ago

@jrudolph can you share the steps how you generated this flame graph (and how you read it)?

olafurpg commented 4 years ago

You can generate flame graphs with https://github.com/jvm-profiling-tools/async-profiler