Scala 經常遇到需要去重和取交集的情況,這裏對Set簡單使用和性能進行分析:
val a = Set(1,2,3)
val b = Set(2,3,4)
1.交集
println(a & b)
println(a intersect(b))
2.並集
println(a ++ b)
println(a | b)
println(a.union(b))
3.差集
差集需要注意前後順序的區別,會造成最終結果的不同,前面交集和並集不守影響
4.增加刪除元素
A.直接調用api
a.add(9)
a.remove(10)
B.直接加減 需要注意類型一致
println(a + (1,9))
println(a - (1,9))
C.這裏需要注意的是++= 和 ++ , --= 和--有區別,++=和--=會影響原始集合,++和--則不會影響原始集合,只執行當次操作
println(a ++ b)
println(a)
println(a ++= b)
println(a)
Set(1, 2, 3, 4)
Set(1, 2, 3)
Set(1, 2, 3, 4)
Set(1, 2, 3, 4)
5.Set性能分析
大量數據去重情況下,先聚合所有數據再去重,還是逐條去重
A.先定義一個生成Array的函數:
def genArr(): Array[Int] = {
val tmp = new ArrayBuffer[Int]()
for (i <- 0 to 5){
tmp.append(scala.util.Random.nextInt(10000))
}
tmp.toArray
}
B.逐條去重
val st1 = System.currentTimeMillis()
var featSet: Set[Int] = Set()
for (i <- 0 to 10000) {
featSet ++= genArr().toSet
}
println(featSet)
val st2 = System.currentTimeMillis()
C.先聚合再去重
val st3 = System.currentTimeMillis()
var featArr = new ArrayBuffer[Int]()
for (i <- 0 to 10000) {
featArr ++= genArr()
}
print(featArr.toArray.toSet)
val st4 = System.currentTimeMillis()
D.查看時間
10條數據時:
逐條處理 37
聚合再處理 1
10000條數據時:
逐條處理 338
聚合再處理 40
Tip:本地測試兩次都是先聚合再處理的速度快,不過在生產環境中也遇到過相反的情況,總的來說,數據比較少或者佔內存小,一般情況先聚合再生成set的效率高一些;數據很大,或者本機內存不足時,逐條處理效率會略優於先聚合在處理