Kotlin is very smart under the hood. We cannot declare primitives in Kotlin, but they are used when we don’t use a variable like an object. For instance, look at the following example:

var i = 10

i = i * 2

println(i)

This declaration uses primitive int under the hood. This is its representation in Java:

// Java

int i = 10;

i = i * 2;

System.out.println(i);

How much faster is this implementation than the one that uses Integer ? Let’s check it out. We need to define both ways in Java:

public class PrimitivesJavaBenchmark {



public int primitiveCount() {

int a = 1;

for (int i = 0; i < 1_000_000; i++) {

a = a + i * 2;

}

return a;

}



public Integer objectCount() {

Integer a = 1;

for (Integer i = 0; i < 1_000_000; i++) {

a = a + i * 2;

}

return a;

}

}

When you measure performance of this two methods, you will notice a huge difference. In my machine one that uses Integer needs 4 905 603 ns, while the one that uses primitive needs 316 594 ns (check it out yourself). This is 15 times less! This is a huge difference!

How is it possible that we have such a difference? Primitives are much lighter than objects. They are just a number located in memory. They don’t need everything around OOP. When you see this difference then you should be grateful that Kotlin uses primitives whenever possible and we don’t even need to be aware of this fact. Although you should be aware that there are some things that prevent compiler from using primitive:

Nullable type cannot be primitive. Compiler is smart and when it dedicates that you are not setting null then it uses primitive. If it is not sure, then it needs to use non-primitive type. Remember that this is an additional cost of nullability in performance critical parts of your code.

Primitives cannot be used as a generic type argument.

The second problem is especially important because we rarely have performance critical parts of code that processes just numbers, but we often have one that operates on a collection of elements. This is a problem because every generic collection uses non-primitive type. For example:

List<Int> is equivalent of Java List<Integer>

is equivalent of Java Set<Double> is equivalent of Java Set<Double>

This fact is a big cost when we need to operate on a list of numbers. Although there is also a solution. There is the Java collection that allows primitives. What is that? Arrays!

// Java

int[] a = { 1,2,3,4 };

If it is possible in Java to use array with primitives, it is also possible in Kotlin. To do it we need to use one of special array types that represents array with different primitives: IntArray , LongArray , ShortArray , DoubleArray , FloatArray or CharArray . Let’s use IntArray and see an impact on the code comparing to List<Int> :

open class InlineFilterBenchmark {



lateinit var list: List<Int>

lateinit var array: IntArray



@Setup

fun init() {

list = List(1_000_000) { it }

array = IntArray(1_000_000) { it }

}



@Benchmark

fun averageOnIntList(): Double {

return list.average()

}



@Benchmark

fun averageOnIntArray(): Double {

return array.average()

}

}

The difference is not so spectacular, but it is always visible. For instance, average function is around 25% faster thanks to the fact that primitives are used under the hood (check it out yourself).

Arrays with primitives are also lighter then collections. When you make measurements, you will find out that above IntArray allocates 400 000 016 bytes, while List<Int> allocates 2 000 006 944 bytes. It is 5 times more!

As you can see, primitives and arrays with primitives can be used as an optimization in performance critical parts of your code. They allocate less memory and their processing is faster. Although improvement in most cases is not significant enough to use arrays with primitives by default instead of lists. Lists are more intuitive and much more often in use, so in most cases we should use them instead. But you should keep in mind this optimization in case you will need to optimize some performance critical part.

Effective Kotlin

This is the second article about Effective Kotlin. We will publish next parts when we see interest so if you want more on this subject, let us know by claps on this article. In Kt. Academy we also work on the book about this subject:

It will cover a much wider range of topics and go much deeper into every single one of them. It will include also best practices published by Kotlin and Google team, experiences of members of Kotlin team we cooperate with, and subjects touched in “Effective Java in Kotlin” series. To support it and make us publish it faster, use this link and subscribe.