Yammer从Scala转向Java
近日,由Yammer雇員Coda Hale發給Typesafe的Scala商業管理層的郵件通過YCombinator被泄漏出來并在GitHub上刊出。該郵件確認Yammer正在將其基礎設施棧從Scala遷回至Java,原因在于Scala的復雜性與性能問題。
\u0026#xD;\nYammer的公關Shelley Risk向InfoQ證實該郵件只代表Coda Hale的個人意見而非Yammer的官方聲明;隨后,Coda Hale又在http://codahale.com/the-rest-of-the-story/上發表了一篇文章。在該文章中,Coda澄清說這個消息是來自于Donald Fischer(Typesafe的CEO)對早前一個tweet的回復。
\u0026#xD;\n更新:近日,Yammer已經發布了聲明,宣布對該問題的立場,聲明證實了上述猜測。聲明還指出任何語言都會有瑕疵(不僅僅是Scala),該郵件只不過是嘗試提出一些建議以改進Scala的性能與其他問題。最后,聲明說到在構建任何高性能項目時(Scala是其產品環境)都有一些問題需要解決;該郵件旨在幫助Scala不斷改進。
\u0026#xD;\n雖然Coda并未打算公開該郵件,但他通過Gist(后來被刪除了)將其放到了GitHub上以獲得其他朋友的反饋;然而,郵件內容后來被共享出來并得到了大范圍傳播。
\u0026#xD;\n回到2010年8月,Coda在Yammer Engineering博客上說他們將要轉向Scala。其目標是繼續運行在JVM(出于性能原因)上,這個轉變的結果就是減少了約50%的代碼:
\u0026#xD;\nArtie最初的原型采用Java編寫,但在一個周末的試驗中,我嘗試使用Scala 2.8重新實現一次。一天后,代碼行數減少了約一半,并添加了幾個特性。我震驚了,Java開發者很容易找,但Scala團隊卻能完成更多工作\u0026#xD;\n一年過后,這個決定發生了變化:
\u0026#xD;\n目前在Yammer,我們正在將基礎設施遷回至Java,同時以遺留庫的形式繼續對Scala提供支持。這個過程并不是那么急,我們剛剛開始,但需要很長時間。本質在于使用Scala而非Java作為我們的默認語言所產生的摩擦和復雜性并未被足夠的生產力提升或是維護工作的減少而抵消。我們或許還會在產品中使用Scala,但主要的開發將會使用Java。\u0026#xD;\nStephen Colebourne(近日發表了文章Is Scala the new EJB2?)對這封郵件做了點評,其要點總結如下:
\u0026#xD;\n- 作為一門語言,Scala中有很多頗具見地的想法。但它是門非常復雜的語言。\u0026#xD;\n
- 除了Scala所引入的概念與具體實現外,要想編寫地道的Scala還有一個文化的問題,有時突然就蹦出來一個最佳實踐:完全不管不顧社區。\u0026#xD;\n
- 我當然知道學習(以及教授)Scala的困難程度與重要性。因為我們不可能在沒人學習Scala的情況下找到人,這個事實非常重要。\u0026#xD;\n
- 構建工具鏈導致開發很不舒服。這主要是因為SBT導致了Maven與Ant的邊緣化——而他們是Java生態圈中的兩個主要的構建工具。\u0026#xD;\n
- 每個主要的Scala發布都不兼容于之前的版本,這導致Scala開發者總是在開發新的庫并重新發明輪子。\u0026#xD;\n
- 借助于分析與檢查字節碼,我們可以通過采用一些簡單的規則實現100倍的改進:\u0026#xD;\n
- 不要使用for循環\u0026#xD;\n
- 不要使用scala.collection.mutable\u0026#xD;\n
- 不要使用scala.collection.immutable\u0026#xD;\n
- 總是使用private[this]\u0026#xD;\n
- 不要使用閉包\u0026#xD;\n
- 我和開發團隊討論了這個問題(遷回至Java),并且演示了兩個代碼基,結果是大家普遍同意進行切換。毫無疑問,我們肯定對Scala的某些方面還不太熟悉,但這不足以讓我們還固守在Scala上。\u0026#xD;\n
其中一些問題可能不太重要(比如說,一門語言越流行,那么雇傭的開發者的經驗就會越多),其中一些是根據經驗來測試的。比如說,其中一條建議就是不要使用for循環。這可以通過如下代碼進行測試:
\u0026#xD;\n\u0026#xD;\n\u0026#xD;\nscala\u0026gt;\u0026#xD;\n var start = System.currentTimeMillis();\u0026#xD;\n var total = 0;for(i \u0026lt;- 0 until 100000) { total += i };\u0026#xD;\n var end = System.currentTimeMillis();\u0026#xD;\n println(end-start);\u0026#xD;\n println(total);\u0026#xD;\n114\u0026#xD;\nscala\u0026gt;\u0026#xD;\nscala\u0026lt; \u0026#xD;\n var start = System.currentTimeMillis();\u0026#xD;\n var total = 0;var i=0;while(i \u0026lt; 100000) { i=i+1;total += i };\u0026#xD;\n var end = System.currentTimeMillis();\u0026#xD;\n println(end-start);\u0026#xD;\n println(total);\u0026#xD;\n8\u0026#xD;\n\u0026#xD;\n\u0026#xD;\n這里使用for循環(與\"until\"模式,很多Scala程序員都習慣這么用)要比對應的while循環慢很多,雖然使用while循環的可讀性差一些。同樣循環的Java實現對于for和while來說都是2ms。
\u0026#xD;\n我們做的另一個測試是通過從一個包含Integer對象的數據集合中加載來看看可變map的性能(這可以在Java與Scala中進行對比,裝箱的損耗應該差不多)。
\u0026#xD;\n\u0026#xD;\n\u0026#xD;\nscala\u0026gt;\u0026#xD;\n val m = new scala.collection.mutable.HashMap[Int,Int]; \u0026#xD;\n var i = 0;\u0026#xD;\n var start = System.currentTimeMillis();\u0026#xD;\n while(i\u0026lt;100000) { i=i+1;m.put(i,i);};\u0026#xD;\n var end = System.currentTimeMillis();\u0026#xD;\n println(end-start);\u0026#xD;\n println(m.size)\u0026#xD;\n101\u0026#xD;\nscala\u0026gt;\u0026#xD;\n val m = new java.util.HashMap[Int,Int]; \u0026#xD;\n var i = 0;\u0026#xD;\n var start = System.currentTimeMillis();\u0026#xD;\n while(i\u0026lt;100000) { i=i+1;m.put(i,i);};\u0026#xD;\n var end = System.currentTimeMillis();\u0026#xD;\n println(end-start);\u0026#xD;\n println(m.size)\u0026#xD;\n28\u0026#xD;\nscala\u0026gt;\u0026#xD;\n val m = new java.util.concurrent.ConcurrentHashMap[Int,Int]; \u0026#xD;\n var i = 0;\u0026#xD;\n var start = System.currentTimeMillis();\u0026#xD;\n while(i\u0026lt;100000) { i=i+1;m.put(i,i);};\u0026#xD;\n var end = System.currentTimeMillis();\u0026#xD;\n println(end-start);\u0026#xD;\n println(m.size)\u0026#xD;\n55\u0026#xD;\n\u0026#xD;\n\u0026#xD;\n與java.util.HashMap相比,性能是相同的,與java.util.concurrent.ConcurrentHashMap相比,Java的速度要比Scala快一倍。Java集合類超越了Scala(以上測試基于OSX JVM 1.6.0_29與Scala 2.9.1,在文本撰寫之際的最新版本)。
\u0026#xD;\n但遺憾的是,在Scala庫API中有很多Scala集合,他們需要通過代碼中的隱式轉換從Java對象類型轉換為Scala對象類型。出于性能原因,這需要大量的重寫。
\u0026#xD;\n如果Scala編譯器通過invokedynamic生成代碼,那么閉包(lambdas)的性能還會得到改進,這是后續版本的Scala將會做的事情。此外,在JDK 8中(將會給Java帶來native lambdas與method handles)將會有很多的性能改進,這些改進都可以為Scala所用。
\u0026#xD;\n最后,Scala在解決版本之間的不兼容問題上面臨著越來越多的壓力(不僅僅是2.9.2與2.9.3之間的小改進)。Typesafe并未發布Scala未來路線圖的官方聲明,也沒有說明何時才會有穩定的二進制版本能夠實現不同版本之間代碼的兼容。如果能夠實現向后兼容,那么就會有更多穩定的庫出現,并且會形成一個社區倉庫,這對未來有志于使用Scala的開發者將大有裨益。
\u0026#xD;\n查看英文原文:Yammer Moving from Scala to Java
總結
以上是生活随笔為你收集整理的Yammer从Scala转向Java的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百家云上市后首份财报:营收 6860 万
- 下一篇: 终于!魅族20系列官宣 采用直屏设计 发