Codementor Events

Effective Kotlin: Use Arrays with primitives for performance critical processing

Published May 07, 2018Last updated Nov 03, 2018
Effective Kotlin: Use Arrays with primitives for performance critical processing

Originally published on blog.kotlin-academy.com by Marcin Moskała

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:

// Javaint 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>
  • 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 Kotlin 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.


If you need a help with Kotlin, remember that I give consultations.

To be up-to-date with great news on Kotlin Academy, subscribe to the newsletter, observe Twitter and follow.

To reference me on Twitter, use @MarcinMoskala. Use the link below to subscribe to the newsletter:

Discover and read more posts from Kotlin Academy
get started