YammerはScalaからJavaへ

4746 ワード

Yammerの従業員であるCoda HaleがTypesafeのScala商業管理職に送ったメールがYCombinatorを通じて流出し、GitHubに掲載された.このメールは、Javaの複雑さとパフォーマンスの問題のため、YammerがインフラストラクチャスタックをScalaからJavaに移行していることを確認します.
Yammerの広報Shelley RiskはInfoQにこのメールがYammerの公式声明ではなくCoda Haleの個人的な意見を代表していることを確認した.その後、コダホールはhttp://codahale.com/the-rest-of-the-story/に文章を発表した.この文章では、CodaはこのニュースがDonald Fischer(TypesafeのCEO)の以前のtweetへの返事から来たと明らかにした.
更新:Yammerはこのほど、この問題に対する立場を発表し、このような推測を確認した.声明はまた、どの言語にも欠陥があることを指摘しています(Scalaだけでなく)、このメールはScalaの性能とその他の問題を改善するためにいくつかの提案をしようとしているにすぎません.最後に、声明は、高性能プロジェクトを構築する際(Scalaは製品環境)にいくつかの問題を解決する必要があると述べた.このメールはScalaの改善を支援することを目的としています.
Codaはこのメールを公開するつもりはなかったが、Gist(後に削除された)を通じてGitHubに置いて他の友人のフィードバックを得た.しかし、メールの内容は後に共有され、広く伝播された.
2010年8月に戻ると、CodaはYammer EngineeringのブログでScalaに転向すると述べた.JVM(パフォーマンス上の理由)で動作し続けることを目標としています.この移行の結果、コードの約50%が削減されます.
Artieの最初のプロトタイプはJavaで作成されたが,週末の実験ではScala 2.8を用いて再実現を試みた.1日後、コード行数は約半分減少し、いくつかの特性が追加されました.驚いたことにJava開発者は探しやすいが、Scalaチームはもっと多くの仕事をすることができる.
1年後、この決定は変わりました.
現在Yammerでは、インフラストラクチャをJavaに移行しているとともに、Scalaをレガシーライブラリとしてサポートし続けています.この過程はそんなに急ぐわけではありません.私たちは始まったばかりですが、長い時間がかかります.本質は、JavaではなくScalaをデフォルト言語として使用することによって生じる摩擦と複雑さが、十分な生産性の向上やメンテナンス作業の減少によって相殺されていないことです.製品ではScalaも使用するかもしれませんが、主な開発ではJavaが使用されます.
Stephen Coleborne(Is Scale the new EJB 2?)はこのメールについてコメントし、そのポイントを以下にまとめた.
  • 言語として、Scalaには見識のある考えがたくさんあります.しかし、それは非常に複雑な言語です.
  • Scalaが導入した概念と具体的な実現のほかに、本場のScalaを書くにはもう一つの文化の問題があり、時には突然最高の実践が飛び出した:コミュニティを全く顧みない.
  • もちろん勉強(および教授)Scalaの困難さと重要性を知っています.私たちはScalaを学ぶ人がいない状況で人を見つけることはできないので、この事実は非常に重要です.
  • ツールチェーンの構築は開発を不快にさせた.これは主にSBTがMavenとAntのエッジ化を招いたためであり,Java生態圏における2つの主要な構築ツールである.
  • の各主要なScalaリリースは、以前のバージョンと互換性がありません.これにより、Scala開発者は常に新しいライブラリを開発し、ホイールを再発明しています.
  • バイトコードの分析とチェックにより、いくつかの簡単なルールを採用することで、100倍の改善を実現することができます.
  • forループ
  • は使用しない
  • scala.collection.mutable
  • は使用しないでください.
  • scala.collection.immutable
  • は使用しないでください.
  • 常にprivate[this]
  • を使用
  • 閉パッケージ
  • は使用しないでください.
  • この問題について開発チームと議論し(Javaに移行)、2つのコードベースを実証した結果、切り替えに同意しました.間違いなく、私たちは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
    

    ここではforループ(「until」モードを使用し、多くのScalaプログラマーがこのように使用することに慣れている)を使用すると、対応するwhileループよりも遅くなります.whileループを使用すると可読性が悪くなりますが.同じサイクルのJava実装はforとwhileにとって2 msである.
    私たちが行ったもう一つのテストは、Integerオブジェクトを含むデータセットからロードすることで、可変mapの性能を見ることです(これは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.util.HashMapと比較してパフォーマンスは同じで、Java.util.concurrentHashMapと比較してJavaの速度はScalaより倍速い.JavaコレクションクラスはScalaを超えています(以上のテストはOSX JVM 1.6.0_29とScala 2.9.1、テキスト作成時の最新バージョンに基づいています).
    残念なことに、ScalaライブラリAPIには多くのScalaセットがあり、コード内の暗黙的な変換によってJavaオブジェクトタイプからScalaオブジェクトタイプに変換する必要があります.パフォーマンスの理由から、これは大量の書き換えが必要です.
    Scalaコンパイラがinvokedynamicでコードを生成すると、閉パッケージ(lambdas)のパフォーマンスが改善され、後続のScalaが行うことになります.さらに、JDK 8では(Javaにnative lambdasとmethod handlesをもたらす)多くのパフォーマンスの改善があり、これらの改善はScalaに使用できます.
    最後に、Scalaはバージョン間の互換性の問題を解決する上でますます多くの圧力に直面している(2.9.2と2.9.3の間の小さな改善だけではない).TypesafeはScalaの将来の路線図の公式声明を発表していないし、いつ安定したバイナリバージョンが異なるバージョン間のコードの互換性を実現できるかも説明していない.後方互換性が実現されれば、より安定したライブラリが出現し、コミュニティウェアハウスが形成され、将来的にScalaを使用することを志す開発者に役立つだろう.
    Yammer Moving from Scala to Java