BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース YammerがScalaからJavaへ移行中

YammerがScalaからJavaへ移行中

ブックマーク

原文(投稿日:2011/11/30)へのリンク

Yammerの従業員であるCoda Hale氏がScalaの商用ベンダであるTypesafe社へ送ったメールYCombinatorGitHubのgist経由でリークした。メールによれば、Yammerは複雑さや性能面を鑑みて、基盤のインフラをScalaからJavaへ戻すそうだ。

YammerのPR部門のShelley Risk氏によればこのメールはCoda Hale氏の個人的な意見であり、Yammerの公式な見解ではないとのことだ。このリーク後、Coda Hale氏は自身の考えをhttp://codahale.com/the-rest-of-the-story/で表明している。氏はこのメールはDonald Fischer氏(Typesafe社のCEO)からのフィードバックの要請に答えたもので、移行を示唆するツイートを補足したものだと説明している。このメールを公にするつもりはなかったが、氏はこれをGitHubのGist(削除されているが)にアップし、友人からフィードバックを求めた。結果的にこのメールは広く共有された。

2010年8月、氏はYammerのエンジニアリングブログに、リアルタイム機能のためにScalaへ移行していると書いた。目標はJVM上(性能のため)でサービスを提供しつつ、約50%コードを削減することだ。

最初のArtieのプロトタイプはJavaで実装しました。しかし、週末になって試しにScala 2.8で再実装したところ、コードが半分になり、いくつか面白い機能も実装できました。私は納得しました。Javaを雇うのは簡単ですが、Scalaチームの方がいろいろなことができそうです。

しかし、1年と4ヶ月経つと、この決定は反転していた。

今、Yammerでは、基盤インフラをJavaへ移行しています。 Scalaはファザードとレガシなライブラリの部分で使い続けるつもりです。 急いではいません。始めたばかりです。この決定までには時間がかかりました。 Javaの代わりにScalaを使うことで生まれる軋轢や複雑さは、 Scalaの生産性や運用負荷の削減によっては埋め合わせできません。 まだ、Scalaを使っていますし、ずっと使い続けると思いますが、主要な開発はJavaで行うつもりです。

Stephen Colebourne氏は最近Scalaは新しいEJB2かという記事を書いたが、氏はこのメールに箇条書きで注釈を付けている。

  • 言語としてのScalaは興味深い特徴を持っている。しかし、とても複雑な言語でもある。
  • Scalaがもたらす概念や実装に加えて、自然なScalaを書こうとする文化がある。これを突き詰めるとある時点でベストプラクティスが現れる。それは、コミュニティを無視することだ。
  • 後になって気付いたことだが、私はScalaを学ぶこと(教えること)の難しさと重要さを低く見積もりすぎていた。というのは、Scalaの経験のある開発者を雇うのは不可能だからだ。これは思ったよりも遥かに大きな問題だ。
  • 開発に不安を持ち込むのは問題だ。SBTが唯一のツールなのは、MavenやAntの限界を示している。この2つのビルドツールはJavaのエコシステムのものだ。
  • Scalaのメジャーリリースは後方互換性がないので、Scalaの開発者は新しいライブラリを使い、車輪の再発明を促進しやすい。
  • バイトコードの解析と調査を行った結果、100倍も性能が改善される簡単なルールが見つかった。
    • forループを使わない
    • scala.collection.mutableを使わない
    • scala.collection.immutableを使わない
    • private[this]を使う
    • クロージャを使わない
  • 私はこの[Javaへ移行するという]問題をチームに切り出し、ふたつのコードでデモをしたところ、移行することに対してすぐに合意がとれたことに驚きました。Scalaには見落としている点がまだあると思いますが、そのような特徴があってもScalaを使い続ける理由としては不十分です。

このような問題のいくつかは状況に依存する(例えば、経験のある開発者の雇いやすくなればなるほど、ある言語は人気が出る)が、テストをすることもできる。例えば、アドバイスできることのひとつはforループを使わないことだ。これは下記のコードでテストできる。

scala>
  var start = System.currentTimeMillis();
  var total = 0;for(i <- 0 until 100000) { total += i };
  var end = System.currentTimeMillis();
  println(end-start);
  println(total);
114
scala>
scala< 
  var start = System.currentTimeMillis();
  var total = 0;var i=0;while(i < 100000) { i=i+1;total += i };
  var end = System.currentTimeMillis();
  println(end-start);
  println(total);
8

上記の'until'を使ったforループ(多くのプログラマが普通だと思っている書き方)の処理は、whileを使ったループの処理に比べて読みやすいが、とても遅い。Javaの同様のループ処理の場合の結果は、forでもwhileでも同じ2ミリ秒だ。

mutableのマップにIntegerオブジェクトのデータセットをロードするを使った別のテストも行った(今回はJavaとScalaを比較した。ボキシングのコストは同等と想定する)。

scala>
  val m = new scala.collection.mutable.HashMap[Int,Int]; 
  var i = 0;
  var start = System.currentTimeMillis();
  while(i<100000) { i=i+1;m.put(i,i);};
  var end = System.currentTimeMillis();
  println(end-start);
  println(m.size)
101
scala>
  val m = new java.util.HashMap[Int,Int]; 
  var i = 0;
  var start = System.currentTimeMillis();
  while(i<100000) { i=i+1;m.put(i,i);};
  var end = System.currentTimeMillis();
  println(end-start);
  println(m.size)
28
scala>
  val m = new java.util.concurrent.ConcurrentHashMap[Int,Int]; 
  var i = 0;
  var start = System.currentTimeMillis();
  while(i<100000) { i=i+1;m.put(i,i);};
  var end = System.currentTimeMillis();
  println(end-start);
  println(m.size)
55

普通のJavaのコードと比べるとjava.util.HashMapの場合は性能は同じだ。java.util.concurrent.ConcurrentHashMapを使った場合はJavaの方が同じScalaのコードと比べて2倍速い。両方ともScalaのHashMapよりも性能が良い。(計測環境はOSXとJVM 1.6.0_29、Scala 2.9.1。Scalaはこの記事を書いたときの最新のバージョン。)

残念ながらScalaのコレクションはScalaのライブラリAPIで広く使われている。従って、上記のコード上ではJavaオブジェクト型からScalaオブジェクト型に暗黙に変換される。くだんのメールによれば、これが性能問題を引き起こし、大幅な書き換えの原因になった。

Scalaのコンパイラがinvokedynamicを使ったコードを生成すれば、クロージャ(ラムダ)の性能は改善するかもしれない。これはScalaの将来のバージョンのコンパイラで実現するかもしれない。加えて、JDK 8(ネイティブのラムダとメソッドハンドルを提供する予定)には多くの性能上の長所があるので、将来のScalaもこれらの利点の恩恵を受けることができるだろう。

そして、Scalaに対して各リリース(2.9.2から2.9.3へのマイナーバージョンアップで互換性を維持するだけでなく)の後方互換性を維持するように求める圧力が高まっている。ScalaのロードマップについてはTypesafe社から正式な発表はない。また、いつコンパイルされたバイナリが各リリース間で後方(あるいは前方)互換性があるようになるのかも分からない。後方互換性があるようになれば、より安定したライブラリをリリースし、Scalaに興味がある開発者が誰でも利用できるコミュニティ用のリポジトリを準備することも出来る。

この記事に星をつける

おすすめ度
スタイル

BT