• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Scalaのコンパイルを3倍速くした話
 

Scalaのコンパイルを3倍速くした話

on

  • 191 views

<marquee>

<marquee>

Statistics

Views

Total Views
191
Views on SlideShare
187
Embed Views
4

Actions

Likes
0
Downloads
0
Comments
0

1 Embed 4

https://twitter.com 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Scalaのコンパイルを3倍速くした話 Scalaのコンパイルを3倍速くした話 Presentation Transcript

    • TBD
    • 自己紹介 • @todesking • ジャバ(バッチ) → Ruby(ソシャゲサーバサ イド) → Scala(広告システムサーバサイド)
    • 近況 • ビルドシステムと戦っている http://twitter.com/todesking/status/488675512424734720! sbt/ivy使えばパッケージ管理の問題を解決してくれるというのは幻覚だったということがわかった、社会は厳しい
    • 何はともあれ • みんな大好きなあの話をします
    • Scalaのコンパイルが 3倍 速くなった話
    • 問題 https://twitter.com/todesking/status/449393123894906880! Scala、みんなコンパイルの遅さに困ってるが解決手段が無いためコンパイル中に音楽を流すプラグインを作成して慰みを得ているということがわかった。Ruby 使ったほうがいいと思う。!
    • (́・_・`) • https://twitter.com/ todesking/status/ 449406714123927553
    • どれくらい遅いか [Info] Compiling 278 Scala sources and 4 Java sources to target/scala-2.10/classes... . . . . . . . .[success] Total time: 425 s
    • ?! • 他のプロジェクト [info] Compiling 234 Scala sources and 5 Java sources to target/scala-2.10/ classes... . . [success] Total time: 64 s ! はやい(相対的に)
    • さすがに死っぽいので 調査しました • 特定のプロジェクトだけすごく遅い • プロジェクトの設定? • 使用ライブラリ?
    • hprof: JVM標準 プロファイラ • jvmオプションつけてsbt compile • 結果はjava.hprof.txtに出力されま す $ sbt -J-agentlib:hprof=cpu=samples,depth=5 clean compile
    • 結果見る • depth=5で荒い解析 • クラスのロードが大量にされている……? rank self accum count trace method 1 12.04% 12.04% 2158 300093 java.util.zip.ZipFile.getEntry 2 9.90% 21.95% 1775 300065 java.lang.Throwable.fillInStackTrace 3 7.21% 29.16% 1293 303874 java.lang.Class.forName0 4 5.40% 34.56% 967 300200 java.lang.Throwable.fillInStackTrace 5 2.76% 37.32% 495 300061 java.lang.ClassLoader.defineClass1 6 1.66% 38.98% 298 300616 java.lang.ClassLoader.findLoadedClass0 7 1.32% 40.30% 236 303922 scala.collection.IndexedSeqOptimized$cl 8 1.27% 41.57% 228 303902 scala.collection.IndexedSeqOptimized$cl 9 1.27% 42.84% 228 301496 java.net.SocketInputStream.socketRead0 10 1.15% 43.99% 206 300711 java.lang.ClassLoader.findLoadedClass0 11 1.03% 45.02% 184 304106 java.lang.Class.forName 12 0.95% 45.97% 170 300630 java.lang.ClassLoader.loadClass 13 0.86% 46.83% 155 304054 java.lang.Object.hashCode 14 0.84% 47.68% 151 303870 java.io.UnixFileSystem.getBooleanAttrib 15 0.84% 48.51% 150 303879 java.lang.ClassLoader.loadClass 16 0.81% 49.33% 146 304060 java.security.AccessController.doPrivil
    • スタックトレースの詳細 • 処理時間上位の処理を見ていく • この処理がどこから呼ばれてるかを知りたい • スタックトレースの深度を増やして再実行 TRACE 300093: java.util.zip.ZipFile.getEntry(ZipFile.java:Unknown java.util.zip.ZipFile.getEntry(ZipFile.java:306) java.util.jar.JarFile.getEntry(JarFile.java:226) java.util.jar.JarFile.getJarEntry(JarFile.java:209) sun.misc.URLClassPath$JarLoader.getResource(URLClass
    • 結果見る • depth = 50 • トレース深度を増やしてみる CPU SAMPLES BEGIN (total = 22833) Tue Jul 15 15:02:57 2014 rank self accum count trace method 1 0.58% 0.58% 132 312316 java.util.zip.ZipFile.getEntry 2 0.56% 1.14% 128 313147 java.util.zip.ZipFile.getEntry 3 0.53% 1.67% 121 313118 java.util.zip.ZipFile.getEntry 4 0.45% 2.12% 103 313343 java.lang.Object.hashCode 5 0.44% 2.56% 100 313093 java.util.zip.ZipFile.getEntry 6 0.42% 2.98% 96 306293 java.net.SocketInputStream.socketRea 7 0.42% 3.39% 95 312675 java.util.zip.ZipFile.getEntry 8 0.38% 3.78% 87 314506 java.util.zip.ZipFile.getEntry 9 0.36% 4.14% 83 313104 java.lang.Class.forName0 10 0.32% 4.45% 72 306826 java.net.SocketInputStream.socketRea 11 0.29% 4.74% 66 312099 java.util.zip.ZipFile.getEntry 12 0.28% 5.02% 63 313314 java.lang.Class.forName0 13 0.27% 5.29% 61 313184 java.lang.Class.forName0 14 0.25% 5.54% 57 312970 java.lang.Throwable.fillInStackTrace 15 0.25% 5.79% 57 313083 java.util.zip.ZipFile.getEntry 16 0.24% 6.03% 55 312783 java.lang.Class.forName0
    • 結果見る • 怪しいものが TRACE 313147: java.util.zip.ZipFile.getEntry(ZipFile.java:Unknown line) java.util.zip.ZipFile.getEntry(ZipFile.java:306) java.util.jar.JarFile.getEntry(JarFile.java:226) java.util.jar.JarFile.getJarEntry(JarFile.java:209) : scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.eval(ToolBoxFactory.scal scala.reflect.macros.runtime.Evals$class.eval(Evals.scala:16) scala.reflect.macros.runtime.Context.eval(Context.scala:6) scalikejdbc.SQLInterpolationMacro$.selectDynamic(SQLInterpolationMacro. sun.reflect.GeneratedMethodAccessor3.invoke(<Unknown Source>:Unknown li java.lang.reflect.Method.invoke(Method.java:606) scala.tools.nsc.typechecker.Macros$$anonfun$scala$tools$nsc$typechecker
    • 原因特定 • scalikejdbcのマクロが原因 • context.eval()が遅い 26 object SQLInterpolationMacro {! 27 ! 28 def selectDynamic[E: c.WeakTypeTag](c: Context)(name: c.Expr[ 29 import c.universe._! 30 ! 31 val nameOpt: Option[String] = try {! 32 Some(c.eval(c.Expr[String](c.resetAllAttrs(name.tree.dupl 33 } catch {! 34 case t: Throwable => None! 35 }! 36
    • ツイッター便利 https://twitter.com/todesking/status/461816289086820352
    • 修正しました • [success] Total time: 122 s • scalikejdbc 1.7.7からは速いよ https://github.com/scalikejdbc/scalikejdbc/pull/241
    • 学び • 基本的にコンパイルは遅い(社会は厳しい) • でもユースケースによっては高速化の余地が! • コンパイラがJVM上で動くので既存のプロファ イリングノウハウが使えて便利 • Scalaエコシステムはフロンティア • 目が届いてないとこが残ってるのでコントリビュートチャン スだ • ツイッター便利