Kotlin 性能优化利器 —— Sqeuence 原理浅析
前言
本文將介紹 Kotlin 中 序列(Sequence)的概念及使用,并介紹該惰性集合操作對集合鏈?zhǔn)秸{(diào)用性能優(yōu)化背后的原理。
目錄
序列(Sequence)
概念
在使用 Kotlin 集合操作符進行鏈?zhǔn)秸{(diào)用時,例如 map 和 filter 時,都會在函數(shù)內(nèi)部創(chuàng)建中間集合,比如下面的例子,使用 map 和 filter 在 User 集合中篩選出性別為男的成員,返回結(jié)果是一個集合。
users.map(User :: sex).filter {it.sex.equals("male")}序列的用法
序列的用法很簡單,只需要再集合后添加asSeqence() 函數(shù)即可
users.asSequence().map(User :: sex).filter {it.sex.equals("male")}這里插播一個概念,其中 User :: user 是成員引用,具體介紹如下
成員引用(Member References)
概念
成員引用可以使你方便的調(diào)用某個類的成員,這個成員包括對應(yīng)類的屬性或方法.雙冒號前的是被引用的類,雙冒號后是需要返回的屬性或方法名,如下所示是返回 User 成員的 sex 屬性:
User :: sex成員引用可以方便的賦值給其他變量或函數(shù),例如上述尋找性別為 male 的例子,也可以用稍微復(fù)雜的寫法,如下:
users.map(user : User -> user.sex).filter {it.sex.equals("male")}可見成員引用的寫法可讀性更強。
再談序列
讓我們回到序列介紹。上文提到使用 map 和 filter 時,都會在函數(shù)內(nèi)部創(chuàng)建中間集合,這會導(dǎo)致一個問題,如果源列表,就是 users 中元素特別多,集合的鏈?zhǔn)教幚頃兊檬值托?#xff0c;原因是創(chuàng)建了多次中間集合。而如果先將待處理集合通過 asSequence() 方法轉(zhuǎn)換為序列,再進行 map 和 filter 操作,就會變得十分高效。對于是否使用序列進行集合操作,有幾個前提,如果使用不當(dāng),反而會造成性能損失。這里總結(jié)一下使用場景:
序列性能測試
上文提到,是否使用序列的條件之一是處理大量數(shù)據(jù),那么這個閾值究竟是多少?下面來進行一個性能測試,構(gòu)造一個商品列表,其中每個商品包含商品名和價格兩個屬性,現(xiàn)在要求出對每個商品的價格加價 100 后,價格為奇數(shù) 的商品的個數(shù),這里用到了 count() 方法,作用是求得集合內(nèi)滿足 count 條件的元素的個數(shù),代碼如下:
/*** 商品類*/ data class Commodity(var name: String, var price: String) import java.util.*fun main(args: Array<String>) {val commodityList = ArrayList<Commodity>()for (i in 0..1000000) {val goods = Commodity("商品 $i", i * 5)commodityList.add(goods)}val startTime = System.currentTimeMillis()commodityList.asSequence() // 使用此函數(shù)代表使用 Kotlin 序列功能.map { it.price + 100 }.count { it % 2 != 0 }println("consume time is ${System.currentTimeMillis() - startTime} ms")}測試結(jié)果折線圖如下,其中橫坐標(biāo)為集合內(nèi)元素的個數(shù),縱坐標(biāo)為代碼執(zhí)行時間,橙色線代表未使用序列,藍色線代表使用序列:
表格對比如下:
由圖可得出如下結(jié)論:
- 上文提到的閾值大致為「一百萬」個元素,大于該閾值時,使用序列大致能帶來 90 % 的性能提升
- 在小于「十萬」個元素時,使用序列反而會造成性能下降
為什么序列會提高集合操作的性能?
- 序列對集合的操作是惰性的。
- 不需要額外的創(chuàng)建中間集合保存鏈?zhǔn)讲僮鞯闹虚g結(jié)果
對于第一點,惰性這個詞可能給人帶來迷惑,這和使用序列后,集合的計算方式有關(guān),下面來介紹這一點,在下面這個例子中,你需要在一個整型數(shù)據(jù)集合,將每個數(shù)乘以 2 ,并找出集合中小于 10 的第一個元素。
var result = listOf(2,4,6,8,10).asSequence.map(it * 2).find(it > 10)find() 方法的作用是在集合中查找滿足條件的第一個元素,并返回查找到的值。下圖是 Kotlin 使用序列進行處理
由圖可知,所謂惰性,就是在使用 map 或 filter 等操作符的時候,在代碼的執(zhí)行順序上,不會優(yōu)先遍歷所有的集合,即偷個懶,先對集合中第一個元素進行 map 和 filter, 然后對該元素執(zhí)行 find 操作,發(fā)現(xiàn)滿足 find 的條件,就立刻返回結(jié)果,由此可見,在有 map 和 find 或 last 等操作符組合時,序列的性能優(yōu)化能發(fā)生最大的作用。
小結(jié)
想學(xué)習(xí)更多Android知識,或者獲取相關(guān)資料請加入Android開發(fā)交流群:1018342383。 有面試資源系統(tǒng)整理分享,Java語言進階和Kotlin語言與Android相關(guān)技術(shù)內(nèi)核,APP開發(fā)框架知識, 360°Android App全方位性能優(yōu)化。Android前沿技術(shù),高級UI、Gradle、RxJava、小程序、Hybrid、 移動架構(gòu)師專題項目實戰(zhàn)環(huán)節(jié)、React Native、等技術(shù)教程!架構(gòu)師課程、NDK模塊開發(fā)、 Flutter等全方面的 Android高級實踐技術(shù)講解。還有在線答疑
轉(zhuǎn)載于:https://blog.51cto.com/14332859/2402073
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Kotlin 性能优化利器 —— Sqeuence 原理浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pyinstaller打包后读不到配置文
- 下一篇: 宝付分析程序员怎么提升自己