Почему отправка Kotlin выполняется значительно медленнее по сравнению с Java? - PullRequest
2 голосов
/ 18 июня 2020

Я новичок в Kotlin. Поэтому на практике я попытался использовать его для решения проблем в LeetCode. Вот одна проблема, которую я решил сегодня:
Distinct Subsequence (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

Возникает вопрос, почему решение Kotlin требует так много времени для выполнения по сравнению с Java?

Ответы [ 2 ]

6 голосов
/ 18 июня 2020

Преобразование int[][] в Kotlin равно Array<IntArray>; у вас есть Array<Array<Int>>, что соответствует Integer[][] в Java. Итак, ваш код Kotlin выполняет множество операций по упаковке и распаковке, а Java - нет. См. https://kotlinlang.org/docs/reference/java-interop.html#java -массивы для более подробной информации.

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

должно исправить эту проблему, по крайней мере (без указания лямбда-выражения все элементы будут инициализированы как 0).

5 голосов
/ 18 июня 2020

Я думаю, это можно списать на то, как их бэкэнд раскручивает виртуальную машину и измеряет время. Потому что это также занимает примерно 200 мс, что просто смешно:

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

Я подозреваю, что вы можете рассчитывать на время прогрева около 200 мс, независимо от того, насколько прост код. Хотя, как ни странно, я попытался отредактировать оба из них, чтобы повторить алгоритм миллион раз, прежде чем вернуться, и код Kotlin (после настройки эквивалентности, как описано ниже) постоянно показывает более низкое время выполнения.

Ваш код не Однако это в точности не эквивалент Java. В другом ответе уже упоминался ваш тип внутреннего массива.

И не связан с производительностью, но ваш первый l oop заполняет на одно место больше в Java, чем в Kotlin.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...