Sequence
为什么需要Sequence?
我们一般在 Kotlin 中处理数据集都是集合,以及使用集合中一些函数式操作符 API,我们很少去将数据集转换成序列再去做集合操作。这是因为我们一般接触的数据量级比较小,使用集合和序列没什么差别,让我们一起来看个例子,你就会明白使用序列的意义了。
//不使用Sequences序列,使用普通的集合操作
fun computeRunTime(action: (() -> Unit)?) {
val startTime = System.currentTimeMillis()
action?.invoke()
Log.i("minfo", "the code run time is ${System.currentTimeMillis() - startTime}")
}
fun main() = computeRunTime {
(0..10000000)
.map { it + 1 }
.filter { it % 2 == 0 }
.count { it < 10 }
.run {
Log.i("minfo","by using list way, result is : $this")
}
}
执行结果:
by using list way, result is : 4
the code run time is 2925
在集合操作中添加一句asSequence()
//转化成Sequences序列,使用序列操作
fun main() = computeRunTime {
(0..10000000)
.asSequence()
.map { it + 1 }
.filter { it % 2 == 0 }
.count { it < 10 }
.run {
Log.i("minfo","by using list way, result is : $this")
}
}
执行结果:
by using list way, result is : 4
the code run time is 535
使用普通集合操作和转化成序列后再做操作的运行时间有好几倍差距,也就对应着两种实现方式在数据集量级比较大的情况下,性能差异也是很大的。
Sequences 原理
通过 decompile 上述例子的源码会发现,普通集合操作会针对每个操作都会生成一个 while 循环,并且每次都会创建新的集合保存中间结果。而使用序列则不会,它们内部会无论进行多少中间操作都是共享同一个迭代器中的数据。
序列中工作原理是逐个元素执行不同的操作,而不是像普通集合所有元素先执行 A 操作,再所有元素执行 B 操作。这是因为序列内部始终维护着一个迭代器,当一个元素被迭代的时候,就需要依次执行 A,B,C 各个操作后,如果此时没有末端操作。
网友评论