たにしきんぐダム

プログラミングやったりアニメやゲーム見たり京都に住んだりしてます

Instant scalafmt startup using SubstrateVM

github.com

scalafmtはscalametaを利用したscalaのコードフォーマッタです。intellij plugin・sbt plugin・climavenやgradle plugin といった様々な形で提供されており

と様々な方法で利用することができます。

scalafmtの課題の一つはscalafmtの実行にかかる時間です。機能が豊富で複雑なため、ただでさえそれなりに実行に時間がかかってしまうのですが、さらに悪いことにscalafmtの実行に当たってはjvm の起動がオーバーヘッドとなってきます。利用頻度が少ないのならば問題ないのですが、gofmtなどのような軽量なフォーマッタのように気軽に実行できないものだろうか。

このjvm起動のオーバーヘッドを解決する方法の一つがnailgunです。nailgunはJVMプロセス(サーバ)をあらかじめ起動しておいて、クライアント側からサーバー側にjavaプログラムの実行要求をし、サーバー上でプログラムを実行させることでjvmの起動によるオーバーヘッドを解決してくれます。scalafmtからの利用方法

github.com

他の解決方法としてはどうにかしてscalafmtをネイティブバイナリにAOTコンパイルしてしまうことですが、残念ながらv1.6.0-M4段階ではscalanativeサポートはされていません Support Scala Native · Issue #1172 · scalameta/scalafmt · GitHub

しかしGraalVMのツールチェーンの一つであるsubstratevm(とgraal)を使うことでscalafmtをAOTコンパイルしnailgunなしに爆速で実行することができるようになります。

SubstrateVM

  • graal/substratevm at master · oracle/graal · GitHub
  • javaで書かれた(生成されるネイティブイメージに)組み込み可能なVM(ランタイム?)、graalコンパイラによってjavaアプリケーションと一緒にネイティブコードに変換される
  • java(のサブセット)アプケーションの静的解析を行い、実行に必要なモジュールを検出(しそれ以外は捨てる)、これにより生成されるネイティブイメージのバイナリサイズを小さく抑えることができる。

ただしJavaアプリケーションをAOTコンパイルしてしまうので、(特にdynamic class loadingまわりなど)いくつかの制約がある graal/LIMITATIONS.md at master · oracle/graal · GitHub

scalafmtをAOTコンパイルする

先日scalafmtに上記の制約をパスさせAOTコンパイルを可能にするPRが来ていた!のでこれでscalafmtをネイティブイメージにコンパイルできるぞ!

github.com

ということでビルドしてみる

$ sbt cli/assembly
$ native-image -jar scalafmt-cli/target/scala-2.12/scalafmt.jar

いろいろオプションつけたりはできるけどこれでネイティブイメージがビルドできた。楽すぎる...

パフォーマンスの計測

実行環境

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS"

$ java -version
openjdk version "1.8.0_172"
OpenJDK Runtime Environment (build 1.8.0_172-20180625212755.graaluser.jdk8u-src-tar-g-b11)
GraalVM 1.0.0-rc5 (build 25.71-b01-internal-jvmci-0.46, mixed mode)


$ cat /proc/cpuinfo | grep "model name" | uniq
model name      : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz

$ cat /proc/cpuinfo | grep "physical id"  | uniq
physical id     : 0

$ cat /proc/cpuinfo | grep processor | wc -l
8

$ cat /proc/cpuinfo | grep "cpu cores" | uniq
cpu cores       : 4

パフォーマンスの計測には Merge pull request #1276 from scalameta/fix-quote · scalameta/scalafmt@5a5747f · GitHub でビルドした3種類のscalafmt-cliを利用しました。

  • scalafmt-jvm
    • coursier bootstrapで固めた普通のCLI
  • ng-nailgun scalafmt
    • この方法でビルドした nailgunを利用したscalafmt-cli
    • ただしnailgunサーバーを温めるために予め一度実行しておき、その後計測環境を同じくした上で二回目の実行にかかった時間を実測値とする
  • scalafmt-native
    • substratevmを利用して作ったscalafmtのネイティブイメージ

フォーマットの実行対象は2種類

scalafmtの設定は scalafmt/.scalafmt.conf at c92153e777984db6d69ec359dd1b1115bd2199d6 · scalameta/scalafmt · GitHub

scalameta/scalafmt全体

$ /usr/bin/time ./scalafmt-jvm
Reformatting...
  100.0% [##########] 142 source files formatted
37.98user 0.69system 0:06.11elapsed 632%CPU (0avgtext+0avgdata 1001288maxresident)k
0inputs+41984outputs (0major+250221minor)pagefaults 0swaps

$ /usr/bin/time ./scalafmt-native
Reformatting...
  100.0% [##########] 142 source files formatted
6.57user 0.17system 0:02.67elapsed 251%CPU (0avgtext+0avgdata 388632maxresident)k
0inputs+952outputs (0major+99109minor)pagefaults 0swaps

$ /usr/bin/time ng-nailgun scalafmt
Reformatting...
  100.0% [##########] 142 source files formatted
0.00user 0.00system 0:01.36elapsed 0%CPU (0avgtext+0avgdata 1796maxresident)k
0inputs+0outputs (0major+73minor)pagefaults 0swaps     

単一ファイル

$ /usr/bin/time ./scalafmt-jvm scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala
12.38user 0.33system 0:02.85elapsed 445%CPU (0avgtext+0avgdata 363232maxresident)k
0inputs+41064outputs (0major+89218minor)pagefaults 0swaps    

$ /usr/bin/time ./scalafmt-native scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala
0.13user 0.04system 0:00.17elapsed 100%CPU (0avgtext+0avgdata 181420maxresident)k       
0inputs+32outputs (0major+41286minor)pagefaults 0swaps 

$ /usr/bin/time ng-nailgun scalafmt scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala  
0.00user 0.00system 0:00.16elapsed 1%CPU (0avgtext+0avgdata 1716maxresident)k    
0inputs+0outputs (0major+70minor)pagefaults 0swaps  

やはりnailgunによる実行が早いのは当然ですが、普通にJVMを起動するCLIの実行と比べるとめちゃくちゃ早くなっていることがわかります:tada: 特に単一ファイルに対するフォーマットの実行のようなshort-live(プロジェクト全体のフォーマットと比べて)な実行の場合はnailgunを利用した場合の実行時間にかなり迫っています。

この実行速度(かつnailgun不要)ならエディタ保存時にscalafmt実行とかしても快適に過ごすことができるのではないでしょうか (もっともプロジェクトに関わる全員のscalafmtのバージョンを揃えないとフォーマット結果がバラバラになりうるのであまり推奨はできない気がする)

所感

scala-nativeが出たときにscala->llvm ir->nativeよりも、scala->jvm bytecode->nativeでネイティブイメージ作れたほうが、scala-nativeが頑張ってるような再実装の嵐を免れることができてお得だよなぁ、実際にはいろいろ制約あって難しいのかなぁと考えていたのですができてしまったよ...

サーバープログラムのようなlong-liveなプロセスに対してはHotSpotVMなどのJITの恩恵が大きそうですが、フォーマッタやlinterやその他CLIツールのようなshort-liveなプロセスにとっては非常に嬉しいツールですね、ありがとうoracle。仕組みがいまいち追いきれてない(論文もsubstratevmに関してはどれを読めばよいのか)なので頑張ってコード読むなりして勉強していきたい。

参考資料

東福寺 - 通天橋

三連休初日、あまりにも天気が良かったのでぶらっと自転車で東福寺に行ってきた、目当ては通天橋。上の写真は通天橋遠景で通天橋に入場するには東福寺境内から入場料400円支払う必要がある。

www.tofukuji.jp

なんで通天橋に行きたかったというと、最近リリースされた Clean Bandit - Solo feat. Demi Lovato [Japan Edition] の1シーンに通天橋の上でダンサーが踊っているシーンを見てハッとなったからであった。 1分56秒あたりから


Clean Bandit - Solo feat. Demi Lovato [Japan Edition]

https://sociorocketnewsen.files.wordpress.com/2018/09/clean-bandit3.jpg?w=1024&h=576

下記サイトより soranews24.com


この辺が橋の中心部、踊ってたところですね

続きを読む

ターナー・南禅寺・ブルーボトルコーヒー

今日は午後お仕事をお休みさせてもらって、京都市文化博物館で催されていたターナー展へ行き、その後南禅寺ブルーボトルコーヒーに行ってきた。

ターナー

turner2018.com

すごく好きで画集をよく見ていたのだけれど、改めて印刷と本物の違いを感じた。質感の違いとか、作品に合った額に入ってるかでこんなにも違うものなんだな...。雲や蒸気や海景や遠方の景色の色使いがが印象的で好きだったのだけれど、建物を含んだ風景のエッチングや詩集の挿絵も良くて惚れ直した。

4月24日からは東京でも展示されるようなので是非行ってくれ!

南禅寺

その後、以前から気になりつつも18時に閉店のためなかなか行けてなかったブルーボトルコーヒーに行くために、烏丸御池駅から東西線に乗り蹴上駅まで。雲一つない快晴だったので山がよく見えてはしゃいでいた。

南禅寺というよりは、南禅寺の周辺の木々が生い茂り木漏れ日が差し込む整備された道が好き。社会人になって平日の昼間に出歩くことがなくなって忘れていたけれど、こういう景色が街のすぐ近くに同居しているから京都は好きなのだよなと思い出した。

平日昼間でも賑わっていた

ブルーボトルコーヒー

ついに京都に出来た!まさかの南禅寺前!しかも18:00閉店ということでなかなか行けずにいたブルーボトルコーヒー京都。コーヒーのお味はいわずもがな、店構えが素敵。

カフェのある建物が奥側にと、道路側に豆などが売られている建物、そしてその間に中庭があり、自由にコーヒーを楽しめる。また行こう。

京都に住んでいると家から電車で3駅程度でこういった景色に会いにいけるので本当にお得、次は自転車でどこかに出かけよう。

ScalaMatsuri 2018 / OSS Hackathon に参加しました

ScalaMatsuri 2018|日本最大級の Scala のカンファレンス

2018年3月16日(金)の Scala OSS ハッカソン / 2018年3月17日~18日の Scalamatsuri2018 に参加しました。楽しかった!

OSS ハッカソン

blog.scalamatsuri.org

ソイヤッて申し込んで良かった。scalikejdbc/scalikejdbcskinny-framework/skinny-framework のプロジェクトへ参加しました。

最終的にハッカソンで取り組んだPRはこれらのPR

@seratchさんにいろいろアドバイスや現状のコードの経緯を聞きつつも、後者はハッカソン時間中にPRを出すに至らず...後日javadocを読み漁って何とかPRを出してマージしていただけました!ハッカソンに参加したからこそ貢献へのとっかかりが掴めたし、シュッとPRを出せました。参加してよかった。 @seratchさんも運営の皆様も本当にありがとうございました!

これからもやっていくぞ

Day1

会場付近の 東京お台場 大江戸温泉物語 | 大江戸温泉物語グループ【公式サイト】 に宿泊していました。早めに目が覚めてしまったので、お台場のそこらへんのカフェーで時間をつぶそうと思ったのだけれど休日朝のお台場ほんとに何もないな!!!コンビニでパンを買って海を眺めたりしてた。

LEGACY CODE FROM DAY ONE / @kubukoz さん

Legacy code from day one

ソフトウェア開発プロジェクト進行におけるアンチパターンのお話

  • コードレビューはしない!
  • コードレビューは時間の無駄。なぜなら俺のコードはいつでも完璧だから
  • nitpickなレビューに一番こだわる
  • 統一的なルールに従わないコードフォーマットの推奨や、高度な技術を取り入れない
  • 早すぎる最適化や、早すぎるモジュール化...

などなどのアンチパターンを面白く話してくださいました。他にもプロジェクト進行におけるアンチパターンやソフトウェアメンテナンスにおけるアンチパターンなどなど、資料面白い。

sbt 1 / @eed3si9n さん

まず Lamport, Leslie. "Time, clocks, and the ordering of events in a distributed system." Communications of the ACM 21.7 (1978): 558-565 を引用してそもそも concurrent の定義を説明して、sbt の DSL ではどのように concurrent な処理を(直感的に)記述できるかということを説明していただいた。非常に分かりやすかった。

そして、sbt1 での 統一的スラッシュ構文や、sbt server による LSP サポート http://eed3si9n.com/ja/sbt-1-1-0-RC1-sbt-server の紹介。scalaで乱立するLSP実装は各所が共同してやっていくワーキンググループができたので、お互い歩み寄っていっているという話を聞いた。


この日は午後から用事があったため、ここで会場を後にした。懇親会に参加できなかったの残念...!

DAY2

朝ごはんです。コーヒーも美味しかった...

JDKのリリースサイクルの変更がScalaにどう影響するか聞きたい

きしださんxuwei-k さんが中心になってお話していただいた。

このあたりのお話?

java 9,10 は短期サポート(半年) Oracle JDK に関しては 11 が 3年のLTS。なので、9,10に関しては手元できちんと動作することをテストしておきつつ、本番環境のバージョンアップはドーンと11まで上げるのが省エネなのではという話を聞いた。 しかし OpenJDK の 11 が LTS という話は特に聞かない気がする。Oracle氏〜

JVM Webアプリケーション メトリクス モニタリング

  • メトリクス取得
  • メトリクスの形式は
    • key value形式 -> (jmx や dropwizard) もう古いぜ
    • key+labels value形式
  • 最低限見てほしいもの
    • heap usage
    • gc lifecycle
    • thread pool
    • connection pool
    • アプリケーション固有のカスタムメトリクス
    • cpu / リクエスト数 / レスポンスタイム / ジョブキュー

などなど

あと3日でJava 10がリリースですが、興味ある人いますか?

出ましたね!

まだ内容追えてない...!

ノベルティ / たこ焼き

何故かたこやき配布してた。美味しかった

個人的に気に入ったノベルティの靴下と箸。珍しい! 箸は開けてみると何も書かれてないただの上等な箸だった! 株式会社ファンコミュニケーションズ さんはそれで良いのか!と思ったけれど逆に強烈に印象に残っているし、この箸使うたびに思い出している。

scala matsuri 2018 本当に楽しかったです。次回は何らかの形で貢献できると良いなと思っています。

シドニー旅行記

4年前、大学一年次の春休みに大学の制度を利用してシドニーに約3週間(2014-02-22 から 2014-03-16)短期語学留学に行ってきた。

Google Photo を整理していたら大量に写真が出てきて懐かしくなったので、記憶にあるうちに旅行記を書いておこう。当時使ってたスマホの写真の画質があまり良くなくて残念!!

留学先

オーストラリア、ニューサウスウェールズ州シドニーに位置する UNSW の留学生向け語学クラスに3週間留学した。

https://www.unsw.edu.au/www.unsw.edu.au

当然たったの3週間では語学力の大幅な向上とかは無理なので異文化交流くらいな気持ち。大学の制度を使っていったので適当な留学エージェントを使うより安価で滞在できた。

(本来車校に通うために貯めてたお金を使って行ったので車の免許は今も持ってない。後悔はしていない)

町並み

Mascot

ホームステイ先はマスコットというシドニー空港のすぐ近く、歓声な住宅街で夜も静かだった。治安は結構良いという話だったけど日本と比べるとまあ良くないので夜はあまり一人で出歩かないようにと釘を刺された。

住宅街の道路です。初日に周囲を散歩してたときの写真、このあと知らないおじさんに宗教勧誘された。

気温・湿度ともに死ぬほど高いのと、ゴミは公道にある巨大ゴミ箱に適当に放り込んでおくみたいなシステムになってるためか道路でゴキブリを見ることが多々あった。日本のより強いし早いしでかい。

大学にはバスで通学していたのだけれど、シドニーの人々、とにかく「thank you」って言う。バス降りるときに運転手に対してもだし、カフェとかコンビニで品物を受け取るときも thank you って言っていた。これ凄く良い文化だと思うので日本に帰国してからも実践してる。

続きを読む