[譯] Kotlin VS Java:編譯速度大比拼

androidwing發表於2016-11-29

原文連結medium.com/keepsafe-en…

譯者:
昨天發表了一篇文章爽翻天!告別Java。一起來使用kotlin開發完整客戶端 評論地下出現了一些不同的看法。這些看法、質疑都是好的,值得提倡的,因為只有這樣,才可以進步,不過我覺得說一個東西不好的前提是有真正瞭解過,使用過,而不是在沒有了解到情況下聽信傳言。也有人提出擔心效能問題,所以找來國外一篇關於編譯速度的文章。

正文:

把一個Java應用程式轉換為Kotlin,編譯時間要多久?

這是關於Kotlin的一系列文章。分為三個部分。 第一部分討論了從Java轉換到Kotlin。第二部分是我對Kotlin的看法。

在前面的文章中, 我討論了把Android 應用從Java 100%轉換為Kotlin 。 Kotlin程式碼比Java的簡潔,更易於維護,所以我認為轉換是值得的。 但有些人不想試用Kotlin,因為他們擔心它編譯可能沒有Java快。 這個關注點絕對是正確的,如果變得編譯很慢,沒有人願意轉換他們的程式碼。 所以,讓我們編譯Lock App試一下 ,然後我把它轉換成Kotlin。 我不會試圖比較一行程式碼的編譯速度; 相反,我將嘗試回答將程式碼從Java轉換為Kotlin是否會影響其總體構建的時間。

我如何測試構建時間

我寫了一個shell來重複執行gradle。 所有測試連續進行10次。 該專案的每個場景之前clean,並使用Gradle daemon ,daemon之前停止一次。
本文中的所有測試都在執行於3.4 GHz的Intel Core i7-6700上,使用32GB的DDR4記憶體和三星850 Pro SSD。 原始碼是用Gradle 2.14.1構建的。

測試

我想在幾種常見的使用場景中執行基準:使用和不使用Gradle daemon+clean,沒有檔案更改的增量編譯,以及更改的檔案的增量編譯。
在轉換之前,App Lock的Java程式碼有5,491個方法和12,371行程式碼。 改寫後,這些數字下降到4,987方法和8,564行Kotlin程式碼。 在重寫期間沒有發生大的架構更改,因此在重寫之前和之後測試編譯時間應該很好地瞭解Java和Kotlin之間的構建時間的差異。

clean + 不用Gradle daemon Build

這是兩種語言中構建時間最差的情況:從冷啟動執行一個clean的構建。 對於這個測試,我禁用了Gradle daemon。
這裡是十個構建所花費的時間:

[譯] Kotlin VS Java:編譯速度大比拼

在這種情況下的結果是,Java構建時間平均為15.5秒,而Kotlin平均為18.5秒:增加了17%。 這對Kotlin來說並不是一個好的開始,但是大部分人不會這麼編譯他們的程式碼。

對於沒有Gradle daemon 並且clean構建,Java編譯比Kotlin快17%

clean +Gradle daemon Build

這個JIT編譯器的問題 ,就像JVM中,是它們需要時間來編譯對報告的執行的程式碼,等等的處理隨時間增加的效能,因為它執行。 如果停止JVM程式,那麼效能增益會丟失。 在構建Java程式碼時,通常在每次構建時啟動和停止JVM。 這迫使JVM每次構建時重做工作。 為了解決這個問題,Gradle附帶了一個守護程式,它將在構建之間保持活躍,以便保持JIT編譯的效能提升。 你可以通過在gradle命令列加引數--daemon或者在gradle.properties檔案新增一句org.gradle.daemon=true。

[譯] Kotlin VS Java:編譯速度大比拼

可以看到,第一次執行所花費的時間與沒有daemon的時間相同,但後續執行的效能提高,直到第四次執行。 在這種情況下,檢視第三次執行後的平均構建時間更有用,其中daemon已工作過了。 對於熱執行,在Java中執行clean構建的平均時間為14.1秒,而Kotlin以16.5秒的速度執行時間:多了13%。

對於clean + Gralde daemon 編譯,Java編譯比Kotlin快13%。

Kotlin正在趕上Java,但仍然稍微落後。 但是,無論使用什麼語言,Gradle daemon都會將構建時間減少40%以上。 如果你還沒有使用它,你應該用上。

所以Kotlin編譯在完整程式碼情況下比Java慢一點。 但是你通常只會對幾個檔案進行更改後編譯,增量構建將有不同的效能。 所以,讓我們來看看Kotlin在增量編譯是否可以趕上。

增量構建

編譯器最重要的效能特性之一是使用增量編譯。 正常構建將重新編譯專案中的所有原始檔,但是增量構建將跟蹤自上次構建以來哪些檔案已更改,並且只重新編譯這些檔案和依賴它們的檔案。 這可能對編譯時間有巨大的影響,特別是對於大型專案。
增量構建在kotlin1.0.2以後版本支援 ,你可以在你的gradle.properties檔案新增kotlin.incremental = true實現。
那麼當使用增量編譯時,Kotlin與Java的編譯時相比如何? 以下是沒有更改檔案時使用增量編譯的基準:

[譯] Kotlin VS Java:編譯速度大比拼

接下來,我們將使用修改後的原始檔測試增量編譯。 為了測試這個,我在每次構建之前改變了一個java檔案,Kotlin也一樣。 在這個基準測試中,原始檔是沒有其他檔案依賴的UI檔案:

[譯] Kotlin VS Java:編譯速度大比拼

最後,讓我們看看使用修改的原始檔進行增量編譯,其中檔案匯入到專案中的許多其他檔案

[譯] Kotlin VS Java:編譯速度大比拼

你可以看到Gradle daemon仍需要兩三次執行來預熱,但是之後兩種語言的效能是非常相似的。 沒有更改,Java每個熱建立4.6秒,而Kotlin平均4.5秒。 當我們更改一個沒有被任何其他檔案使用的檔案時,Java平均需要7.0秒來做一個熱構建,Kotlin是6.1秒。 最後,當我們更改專案中許多其他檔案匯入的檔案時,Java需要7.1秒才能在Gradle daemon加熱後執行增量構建,而Kotlin平均6.0秒。

在最常見的情況下 - 啟用增量編譯的部分構建 - Kotlin編譯速度快或略快於Java。

結論

我們對幾個不同的場景進行了基準測試,看看Kotlin在編譯時間是否可以跟上Java。 雖然Java在clean構建比Kotlin 快10-15%,但這些情況很少。 對於大多數開發人員來說,更常見的情況是部分構建,其中增量編譯進行了大量改進。 隨著Gradle daemon執行和增量編譯的開啟,Kotlin編譯速度快或略快於Java。
這是一個我完全沒有想到並且令人印象深刻的結果。 我必須讚揚Kotlin團隊設計一種不僅具有很多優秀功能,而且能夠快速編譯的語言。
如果你因為編譯時試圖使用Kotlin,你不必擔心:Kotlin的編譯速度和Java一樣快。

相關文章