例如,我们有一个列表,我们想用特定的谓词分成两部分。
首先,我们可以使用filter
和filterNot
。
val trueList = list.filter(predicate)
val falseList = list.filterNot(predicate)
其次,我们可以使用filter
和subtract
:
val trueList = list.filter(predicate)
val falseList = list.subtract(trueList)
第三,我们可以使用groupBy
:
val groupBy = list.groupBy(predicate)
val trueList = groupBy[true]
val falseList = groupBy[false]
什么是最有效,最快捷的方式?我们可以用其他一些功能来做到这一点吗?
我认为subtract
的第二个选项是最糟糕的,我是对的吗?
答案 0 :(得分:1)
因此,我尝试了解哪个选项最快:filter
,subtract
,groupBy
或partition
(感谢Marko Topolnik提示)。我使用measureTimeMillis
来了解每个选项的已用时间:
private fun checkTime(list: List<Int>, predicate: (Int) -> Boolean) {
var sum = 0L
repeat(times) { sum += checkPartition(list, predicate) }
println("partition: ${sum/times}")
sum = 0L
repeat(times) { sum += checkFilter(list, predicate) }
println("filter: ${sum/times}")
sum = 0L
repeat(times) { sum += checkSubtract(list, predicate) }
println("subtract: ${sum/times}")
sum = 0L
repeat(times) { sum += checkGroupBy(list, predicate) }
println("group by: ${sum/times}")
}
private fun checkGroupBy(list: List<Int>, predicate: (Int) -> Boolean): Long {
return measureTimeMillis {
val groupBy = list.groupBy(predicate)
val falseList = groupBy[false]
val trueList = groupBy[true]
}
}
private fun checkSubtract(list: List<Int>, predicate: (Int) -> Boolean): Long {
return measureTimeMillis {
val trueList = list.filter(predicate)
val falseList = list.subtract(trueList)
}
}
private fun checkFilter(list: List<Int>, predicate: (Int) -> Boolean): Long {
return measureTimeMillis {
val trueList = list.filter(predicate)
val falseList = list.filterNot(predicate)
}
}
private fun checkPartition(list: List<Int>, predicate: (Int) -> Boolean): Long {
return measureTimeMillis {
val pair = list.partition(predicate)
val trueList = pair.first
val falseList = pair.second
}
}
我用10次重复检查了这个谓词:
val predicate = { it: Int -> it % 2 == 0 }
使用不同大小的列表:
var list = (1..1_000_000).toList()
checkTime(list, predicate)
分区:16 过滤器:21 减去:81 分组:18
list = (1..2_000_000).toList()
checkTime(list, predicate)
分区:30 过滤器:42 减去:241 分组:36
list = (1..3_000_000).toList()
checkTime(list, predicate)
分区:35 过滤器:59 减去:233 分组:63
因此,partition是将列表分为两部分的非常好的选择。
请告诉我,如果我做错了什么。