准備
一直使用kotlin JVM平台開發服務器的應用,最近想試試看 Kotlin native的性能。
我使用的是 kotlin native 1.3.21,要使用他非常的簡單,下載最新的 IDEA ,我下載的是 IntelliJ IDEA 2018.3.4 (Community Edition),然后新建項目時選擇 “Kotlin/Native”,非常的簡單了。
測試環境如下:
Windows 10 64 位
Intel Core i5-6500 @3.2GHz 4 Core
16GB RAM
測試代碼
這個項目還在初期,所以對應的庫一定還不成熟,所以,我盡力避免使用庫,而且不同的庫實現不同和使用不當,都可能造成測試不准確。
所以我測試簡單的循環,int的位操作,這些指令都是對編譯器的考驗,下面的測試代碼就是檢測一個int32值,包含幾個有效的 1 位。
package sample //import kotlin.random.Random import kotlin.system.measureNanoTime fun main() { runIt() } private fun runIt(){ var sum = 0 val time = measureNanoTime{ //val ran = Random.Default for (i in 0 until 1_0000_0000){ //val v = ran.nextInt() sum += getInt32TrueCount(i) } } // 292 056 900 println("共耗時:$time ns, result: $sum") } private fun getInt32TrueCount(value: Int):Int { if (value == 0) { return 0 } return getByteTrueCount(value and 0xFF) + getByteTrueCount((value shr 8) and 0xFF) + getByteTrueCount((value shr 16) and 0xFF) + getByteTrueCount((value shr 24) and 0xFF) } private fun getByteTrueCount(value: Int) : Int{ if(value== 0){ return 0 } val a = (value and 0x1) val b = ((value and 0x2) shr 1) val c = ((value and 0x4) shr 2) val d = ((value and 0x8) shr 3) val e = ((value and 0x10) shr 4) val f = ((value and 0x20) shr 5) val g = ((value and 0x40) shr 6) val h = ((value and 0x80) shr 7) return a + b + c + d + e + f + g + h }
測試結果
Kotlin有個非常大的好處,常見的庫都可以在 jvm 平台和 native 平台通用,所以上面的代碼可以直接復制到 Kotlin 的jvm環境下執行。
在 Gradle 面板中,找到 Tasks -> run -> runMainReleaseExecutableMingw,就可以運行程序。
耗時如下:
Kotlin Native : 292 056 900 ns
Kotlin Jvm :1 220 617 300 ns
可以明顯看見,native是jvm的 4被性能,我在懷疑是不是 native 的LLVM編譯器 實現了並行,不然怎么差不多4倍呢?
坑
你可能注意到,我注釋了隨機數產生的函數調用,這是因為我發現 native 平台下,默認的隨機數產生非常的慢,遠遠慢於 Jvm 平台。所以庫可能不太成熟。
SIMD
LLVM平台的最大亮點是性能的優化,比如 SIMD,所以我嘗試修改程序,看看是否能啟用SIMD,所以我修改了函數,新代碼如下:
private val m1 = intArrayOf(0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80) private fun getByteTrueCount(value : Int) : Int{ if (value == 0) { return 0 } var sum = 0 for (i in 0 until m1.size){ sum += (value and m1[i] shr i) } return sum }
然而,悲劇發生了,執行時間如下:
Kotlin Native : 80 610 886 500 ns
Kotlin Jvm : 1 297 672 800 ns
最終,native平台花了整整80多秒,你沒有看錯, native慢了很多很多,而JVM平台似乎能聰明的實現了SIMD優化(我猜的)。
至於為什么,我無法知道,
所以,還是比較多的坑。
后記
我提了一個 Issue 給了kotlin native,參見: https://github.com/JetBrains/kotlin-native/issues/2660
他們建議不要使用全局的數組,我修改了,效果不明顯。
另外,他們還建議使用 GCC的內置函數 __builtin_popcount
至於為什么 native 比 Jvm 平台這段代碼要慢的原因,他們的意見是現在還是 beta 哪,不要做性能測試。
雖然有一些問題,但是我任然非常期待 Kotlin native,這樣學會一個 kotlin ,就所有平台通殺了。