scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.86k stars 1.06k forks source link

Investigate inefficient object layouts #3135

Closed smarter closed 2 years ago

smarter commented 7 years ago

Using http://hg.openjdk.java.net/code-tools/jol/ we can inspect the layout of objects on the JVM, this is useful to see if there's anything we can optimize in our code, and to check how our object layout differs from what scalac generates:

$ wget http://central.maven.org/maven2/org/openjdk/jol/jol-cli/0.8/jol-cli-0.8-full.jar

As an example, here's the layout of InitialContext:

% java -jar jol-cli-0.8-full.jar internals -cp $HOME/.ivy2/cache/org.scala-sbt/interface/jars/interface-0.13.15.jar:$HOME/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.3.jar:interfaces/target/dotty-interfaces-0.4.0-bin-SNAPSHOT.jar:out/bootstrap/dotty-library-bootstrapped/scala-0.4/classes:out/bootstrap/dotty-compiler-bootstrapped/scala-0.4/classes 'dotty.tools.dotc.core.Contexts$InitialContext'
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

Failed to find matching constructor, falling back to class-only introspection.

dotty.tools.dotc.core.Contexts$InitialContext object internals:
 OFFSET  SIZE                                                   TYPE DESCRIPTION                               VALUE
      0    12                                                        (object header)                           N/A
     12     4                                                    int Context._period                           N/A
     16     8                                                   long Context.bitmap$0                          N/A
     24     8                                                   long Context.companionMethodFlags              N/A
     32     4                                                    int Context._mode                             N/A
     36     4                                                    int Context.findMemberCount                   N/A
     40     4             dotty.tools.dotc.core.TypeOps.deskolemize$ Context.deskolemize$lzy1                  N/A
     44     4                 dotty.tools.dotc.core.Contexts.Context Context._outer                            N/A
     48     4           dotty.tools.dotc.interfaces.CompilerCallback Context._compilerCallback                 N/A
     52     4                                 xsbti.AnalysisCallback Context._sbtCallback                      N/A
     56     4                       dotty.tools.dotc.core.TyperState Context._typerState                       N/A
     60     4                                        scala.Function1 Context._printerFn                        N/A
     64     4                   dotty.tools.dotc.core.Symbols.Symbol Context._owner                            N/A
     68     4         dotty.tools.dotc.config.Settings.SettingsState Context._sstate                           N/A
     72     4                       dotty.tools.dotc.CompilationUnit Context._compilationUnit                  N/A
     76     4                        dotty.tools.dotc.ast.Trees.Tree Context._tree                             N/A
     80     4                     dotty.tools.dotc.core.Scopes.Scope Context._scope                            N/A
     84     4                    dotty.tools.dotc.typer.TypeAssigner Context._typeAssigner                     N/A
     88     4                      dotty.tools.dotc.typer.ImportInfo Context._importInfo                       N/A
     92     4                 dotty.tools.dotc.core.Contexts.RunInfo Context._runInfo                          N/A
     96     4                                           scala.Option Context._diagnostics                      N/A
    100     4                 dotty.tools.dotc.core.Contexts.GADTMap Context._gadt                             N/A
    104     4                 dotty.tools.dotc.util.FreshNameCreator Context._freshNames                       N/A
    108     4                         scala.collection.immutable.Map Context._moreProperties                   N/A
    112     4                     dotty.tools.dotc.core.TypeComparer Context._typeComparer                     N/A
    116     4                        scala.collection.immutable.List Context.pendingMemberSearches             N/A
    120     4   dotty.tools.dotc.typer.Implicits.ContextualImplicits Context.implicitsCache                    N/A
    124     4                   dotty.tools.dotc.typer.SearchHistory Context._searchHistory                    N/A
    128     4                 dotty.tools.dotc.core.Contexts.Context Context.phasedCtx                         N/A
    132     4               dotty.tools.dotc.core.Contexts.Context[] Context.phasedCtxs                        N/A
    136     4                          java.lang.StackTraceElement[] Context.creationTrace                     N/A
    140     4             dotty.tools.dotc.core.Contexts.ContextBase InitialContext.base                       N/A
Instance size: 144 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

deskolemize probably doesn't need to be a field in every Context. It's especially costly because it's defined as an object and thus translated to a lazy val (which requires an extra field bitmap$0 in the dotty encoding compared to scalac). I just made a PR for this: https://github.com/lampepfl/dotty/pull/3136

dwijnand commented 2 years ago

@smarter worth keeping this one open? If so, mind if we move it to dotty feature requests?

smarter commented 2 years ago

I don't see how it's a feature request, it's a possible performance improvement. I have no opinion on whether keeping it open or closed is better.

SethTisue commented 2 years ago

(this is of course a broader discussion than just this one ticket, but:)

I don't think we should get too hung up on the word "feature". Improving object layout is an enhancement request. dotty-feature-requests seems to us like a better place to keep open-ended, unclear-priority enhancement tickets than here, given Martin's/the-team's ongoing interest in not allowing the number of open tickets in this repo to grow without bounds.

smarter commented 2 years ago

But the feature request repo is supposed to be a user-facing thing, where users can vote on features they care about, not a dumping ground for compiler internals stuff. I'll just close this.

SethTisue commented 2 years ago

"Dumping ground" seems pejorative :-)

How about converting it to a Discussion? We could have a category of discussions for internal-facing enhancement ideas.

smarter commented 2 years ago

I could see discussions working for open-ended stuff like that yeah.