Skip to content

[ETCM-736] Enable compiler optimizations in Prod #963

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 3 commits into from
Apr 14, 2021

Conversation

jb-lunatech
Copy link
Contributor

@jb-lunatech jb-lunatech commented Apr 12, 2021

Description

Enable compiler inlining optimizations as described here https://www.lightbend.com/blog/scala-inliner-optimizer

TL;DR
Don’t enable the optimizer during development: it breaks incremental compilation, and it makes the compiler slower. Only enable it for testing, on CI, and to build releases.
Enable method-local optimizations with -opt:l:method. This option is safe for binary compatibility, but typically doesn’t improve performance on its own.
Enable inlining in addition to method-local optimizations with -opt:l:inline and -opt-inline-from:[PATTERN]
Don’t inline from your dependencies when publishing a library, it breaks binary compatibility. Use -opt-inline-from:my.package.** to only inline from packages within your library.
When compiling an application with global inlining (-opt-inline-from:**), ensure that the run-time classpath is exactly the same as the compile-time classpath.
The @inline annotation only has an effect if the inliner is enabled. It tells the inliner to always try to inline the annotated method or callsite.
Without the @inline annotation, the inliner generally inlines higher-order methods and forwarder methods. The main goal is to eliminate megamorphic callsites due to functions passed as argument, and to eliminate value boxing. Other optimizations are delegated to the JVM.

See also documentation and options renaming ticket

Proposed Solution

  • Enable the optimizations for production only (see option -DmantisDev and flag MANTISDEV)
  • Restrict the optimization to the project since the main goal is to inline logging calls

Do we want to set it for tests and integration tests as well? Switching off dev mode might be a more clear way to achieve this... We agreed to keep it simple : production mode has optimization, dev mode does not, hence to test with inlinine toggle to production mode

Important Changes Introduced

Reminder

To enable dev mode, -DmantisDev=true or MANTIS_DEV=true

Ensuring that compile-time and run-time classpaths are the same

This section is kept for documentation purposes, it has been decided not to enable inline globally

Difference between the classpaths (on my machine, emptied caches)

Compile-time Run-time Issue
(sbt export compile:fullClasspath) (sbt export runtime:fullClasspath)
scala-collection-compat_2.13-2.3.2.jar scala-collection-compat_2.13-2.1.6.jar See below
Scala XML ø Not an issue
Scapegoat plugin ø Not an issue

ScalaPb library is the only library depending on scala-collection-compat (latest 2.4.3) and it also imposes the version of scala-collection-compat to be used. Currently the project depends on ScalaPb 0.10.9 which imposes scala-collection-compat_2.13-2.1.6 (https://github.com/scalapb/ScalaPB/blob/v0.10.9/project/Dependencies.scala#L13) whereas the latest is 0.11.1 imposing scala-collection-compat-2.4.3.
Note : Monix also defines a dependency to scala-collection-compat
via Def.settings https://github.com/monix/monix/blob/cb4823427db8b1f8fdf990bf27b307b396892a76/build.sbt#L89, this potentially explains the discrepancy between the classpaths.

Potential solutions

  • align the version between the compile-time and run-time classpaths, or
  • exclude optimizations fromt the classpath as suggested from libraries (-opt-inline-from:my.package.**)

Testing

  • Inlining changes logs can be seen with the scalac "-Yopt-log-inline", "_" option.
  • Compare compile:fullClasspath vs runtime:fullClasspath
  • Run Mantis

build.sbt Outdated
lazy val compilerOptimizationsForProd = Seq(
"-opt:l:method", // method-local optimizations
"-opt:l:inline", // inlining optimizations
"-opt-inline-from:**" // inlining allowed to all classes
Copy link
Contributor

Choose a reason for hiding this comment

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

wouldn't it make sense to limit this scope?

@jb-lunatech jb-lunatech force-pushed the jbe/feature/ETCM-736-inline-optimizations branch 2 times, most recently from 33d79dd to 20dfe43 Compare April 14, 2021 10:09
Copy link
Contributor

@dzajkowski dzajkowski left a comment

Choose a reason for hiding this comment

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

let's get it in, I'll build a logging wrapper on top of this change. btw would it be possible to enable this by default on CI?

@jonringer
Copy link
Contributor

btw would it be possible to enable this by default on CI?

We don't set any env variables, so I believe they should be getting applied

@jb-lunatech jb-lunatech force-pushed the jbe/feature/ETCM-736-inline-optimizations branch from 20dfe43 to 5321e08 Compare April 14, 2021 15:24
@jb-lunatech jb-lunatech force-pushed the jbe/feature/ETCM-736-inline-optimizations branch from 5321e08 to ed16953 Compare April 14, 2021 16:09
@jb-lunatech jb-lunatech merged commit 2999dde into develop Apr 14, 2021
@jb-lunatech jb-lunatech deleted the jbe/feature/ETCM-736-inline-optimizations branch April 14, 2021 17:39
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.

4 participants