I've recently come across an intriguing situation that I'm hoping to get some clarity on. I've written two versions of a program: one in Kotlin and the other in Java. Despite their functional equivalence, I've noticed a discrepancy in their execution times – the Kotlin version seems to be running noticeably slower than the Java version.
The code below is a solution for a Leetcode problem
Java Code:
import java.util.HashMap;
import java.util.Map;
public class Solution {
public static void main(String[] args) {
int array[] = {2, 7, 11, 15};
int target = 9;
long start = System.nanoTime();
int[] result = twoSum(array, target);
for (int i : result) {
System.out.print(i + " ");
}
long end = System.nanoTime();
System.out.println("\nTime taken =" + (end - start) / 1000);
}
public static int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int a = nums[i];
if (map.containsKey(target - a) && map.get(target - a) != i) {
return new int[]{i, map.get(target - a)};
}
}
return new int[]{};
}
}
Kotlin code:
import kotlin.system.measureNanoTime
fun main() {
val array = intArrayOf(2, 7, 11, 15)
val target = 9
var result: IntArray
var time = measureNanoTime {
result = twoSum(array, target)
result.forEach {
print("$it ")
}
}
time /= 1000
println("\nTime taken =$time")
}
fun twoSum(nums: IntArray, target: Int): IntArray {
val map = HashMap<Int, Int>()
for (i in nums.indices) {
map[nums[i]] = i
}
for (i in nums.indices) {
val b = target - nums[i]
if (map.containsKey(b)) {
val ind = map[b]!!
if (i != ind)
return intArrayOf(i, ind)
}
}
return intArrayOf(0, 0)
}
The average time taken by Java code is 415 micro-seconds, whereas the time taken by Kotlin code is 3185 micro-seconds. The time taken by Kotlin is more than 7.5 times the time taken by the functionally same Java code, which is way too much!
I'm reaching out to the community to see if anyone else has encountered a similar situation or might have insights into the underlying factors contributing to this discrepancy. This post aims to gather insights from the community regarding the factors that might contribute to such variations. Could differences in bytecode generation, compiler optimizations, or perhaps certain language features be influencing this outcome?
JVM version: 1.8
Kotlin compiler version: 1.8.21
[Note: The average time is calculated by running both, Java and Kotlin code, multiple times on the same machine.]