为什么Kotlin提交比Java明显慢?

问题描述 投票:0回答:3

我对 Kotlin 很陌生。为了练习,我尝试用它来解决 LeetCode 中的问题。这是我今天解决的一个问题:
不同子序列(Leetcode)
首先我尝试用Java解决这个问题:

class Solution {
    public int numDistinct(String s, String t) {
        int[][] dp = new int[t.length() + 1][s.length() + 1];
        for (int i = 0; i <= s.length(); i++) {
            dp[0][i] = 1;
        }
        for (int i = 1; i <= t.length(); i++) {
            for (int j = 1; j <= s.length(); j++) {
                if (t.charAt(i - 1) != s.charAt(j - 1)) {
                    dp[i][j] = dp[i][j - 1];
                } else {
                    dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1];
                }
            }
        }
        return dp[t.length()][s.length()];
    }
}

这是该算法的运行时间:

Runtime: 6 ms
Memory Usage: 39.4 MB

然后我尝试在 Kotlin 中解决问题(代码如下):

class Solution {
    fun numDistinct(s: String, t: String): Int {
        var dp = Array(t.count() + 1) {Array(s.count() + 1) {0} }
        for (i in 0 until s.count()) {
            dp[0][i] = 1;
        }
        for (i in 1..t.count()) {
            for (j in 1..s.count()) {
                if (t[i - 1] != s[j - 1]) {
                    dp[i][j] = dp[i][j - 1];
                } else {
                    dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1];
                }
            }
        }
        return dp[t.count()][s.count()]
    }
}

令人震惊的是,上述 Kotlin 实现的算法的运行时间如下:

Runtime: 176 ms
Memory Usage: 34.2 MB

问题是,与 Java 相比,为什么 Kotlin 解决方案需要花费如此多的时间来运行?

java kotlin
3个回答
9
投票

我认为这可以归因于他们的后端如何旋转虚拟机并测量时间。因为这也需要大约 200 毫秒,这很荒谬:

class Solution {
    fun numDistinct(s: String, t: String): Int {
        return 3
    }
}

我怀疑无论代码多么简单,您都可以依靠大约 200 毫秒的预热时间。尽管奇怪的是,我尝试编辑这两个文件以在返回之前重复算法一百万次,并且 Kotlin 代码(在如下所述的等效性调整之后)始终显示出较低的运行时间。

不过,您的代码并不完全等同于 Java。另一个答案已经提到了你的内部数组类型。

与性能无关,但你的第一个循环在 Java 中比在 Kotlin 中多填充了一个空间。


6
投票

int[][]
翻译成 Kotlin 是
Array<IntArray>
;你有
Array<Array<Int>>
,它对应于 Java 中的
Integer[][]
。因此,您的 Kotlin 代码会执行大量装箱和拆箱操作,而 Java 则不会。有关更多详细信息,请参阅 https://kotlinlang.org/docs/reference/java-interop.html#java-arrays

Array(t.count() + 1) {IntArray(s.count() + 1) }

至少应该解决这个问题(不指定 lambda 会将所有元素初始化为

0
)。


0
投票

刚刚注意到 Litcode 修复了他们的 Kotlin 时间测量/性能。 截至今天(2024 年 10 月 17 日),我的 Java 和 Kotlin 速度都是 10-30 毫秒

科特林:

Runtime:16 ms, faster than 100.00% of Kotlin online submissions.
© www.soinside.com 2019 - 2024. All rights reserved.