Kotlin-条件相同:多个if语句或一个if语句

时间:2018-10-22 13:44:18

标签: kotlin

在Kotlin中,您可以使用if语句,类似于三元运算符。

我们可以选择执行以下操作:

val x = if (isOdd) 1 else 2

但是如果我们需要根据某个条件设置多个变量,那么像这样的老式方法是否更正确:

val x: Int
val y: Int
val z: Int

if (isOdd) {
    x = 1
    y = 3
    z = 5
} else {
    x = 2
    y = 4
    z = 6
}

或这样:

val x = if (isOdd) 1 else 2
val y = if (isOdd) 3 else 4
val z = if (isOdd) 5 else 6

第二种方法对我来说看起来更干净,但是我想知道第一种方法是否可以更快地使用计算机,因为它只需要计算一次条件,而第二种方法则需要检查条件3次。

第二种方法是真的变慢了还是会被编译器优化?

3 个答案:

答案 0 :(得分:2)

我更喜欢这样的东西,看起来更像Kotlinesque:

data class Point3D(val x: Int, val y: Int, val z: Int)

fun foo(isOdd: Boolean): Point3D = if (isOdd) Point3D(1, 3, 5) else Point3D(2, 4, 6)

//or using destructureing see https://kotlinlang.org/docs/reference/multi-declarations.html)
val (x,y,z) = if (isOdd) Triple(1, 3, 5) else Triple(2, 4, 6)

它还结合了两者的优点,使用if作为表达式,只需要一个if。 (以额外的对象分配为代价)。

但是要回答您的问题。做自己喜欢的事,认为最易读。性能方面,我怀疑您会有所作为。

答案 1 :(得分:0)

if是Kotlin中的一个表达式,而不是语句:它返回一个值,而在Java中则不是。

老实说,我认为这不是您应该考虑的优化问题。过早的优化是问题的常见根源。如果此布尔变量是线程限定的,那么我认为编译器将执行在这种情况下可能的所有优化,因此几乎完全没有开销(如果不是完全的话)。

OO语言中的明智选择是优先考虑透明性和灵活性,而不是低级优化问题(尤其是当编译器能够解决它们时)。

答案 2 :(得分:0)

好的,所以刚刚再次看到这个问题并感到好奇......所以我做了一些测试。

事实证明实际上存在巨大差异,结果如下:

代码

fun main() {
    for (i in 0 until 3) {
        val t1_s = System.currentTimeMillis()
        for (j in 0 until 100000) {
            when (i){
                0 -> a(j % 2 == 0)
                1 -> b(j % 2 == 0)
                2 -> c(j % 2 == 0)
            }
        }
        val t1_e = System.currentTimeMillis()
        println("Test $i - time ${t1_e - t1_s}")
    }
}

fun a(isOdd: Boolean): Int {
    val x: Int
    val y: Int
    val z: Int

    if (isOdd) {
        x = 1
        y = 3
        z = 5   
    } else {
        x = 2
        y = 4
        z = 6
    }
    
    return x + y + z
}

fun b(isOdd: Boolean): Int {
    val x = if (isOdd) 1 else 2
    val y = if (isOdd) 3 else 4
    val z = if (isOdd) 5 else 6
    
    return x + y + z
}

fun c(isOdd: Boolean): Int {
    val (x,y,z) = if (isOdd) Triple(1, 3, 5) else Triple(2, 4, 6)
    
    return x + y + z
} 

输出

Test 0 - time 3
Test 1 - time 1
Test 2 - time 8

似乎我的第二个解决方案是最快的,接下来是我的第一个建议,而最佳答案要慢得多。

有人知道为什么会这样吗?显然这些是毫秒,所以它几乎总是无关紧要,但认为一种方法快 5-10 倍是很好的

编辑:

因此尝试将迭代次数增加到 100000000,结果是:

Test 0 - time 6
Test 1 - time 41
Test 2 - time 941

我猜前两个选项正在优化,但第三个选项总是创建一个新对象,使其速度很慢

Try it online!