Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generic Interface performance

Simple question, but tricky answer I guess.

Does using Generic Interfaces hurts performance?

Example:

public interface Stuff<T> {

    void hello(T var);
}

vs

public interface Stuff {

    void hello(Integer var);  <---- Integer used just as an example
}

My first thought is that it doesn't. Generics are just part of the language and the compiler will optimize it as though there were no generics (at least in this particular case of generic interfaces).

Is this correct?

like image 457
halfwarp Avatar asked Apr 30 '10 16:04

halfwarp


People also ask

How does generics improve performance in Java?

Code that uses generics has many benefits over non-generic code: Stronger type checks at compile time. A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety. Fixing compile-time errors is easier than fixing runtime errors, which can be difficult to find.

Do generics make code faster?

Monomorphization is a total win for systems programming languages: it is, essentially, the only form of polymorphism that has zero runtime overhead, and often it has negative performance overhead. It makes generic code faster.

Are generics slow Java?

Generics do not affect runtime performance.

Can an interface have a generic type Java?

Java Generic Classes and SubtypingWe can subtype a generic class or interface by extending or implementing it.


1 Answers

There is potential for a minor performance loss, because the compiler sometimes adds synthetic bridge methods. Consider the following example:

public class GenericPerformance {
    public static void main(final String[] args) {
        final Stuff<Integer> stuff = new IntStuff();
        final Integer data = stuff.getData();
        stuff.putData(data);
    }
}

interface Stuff<T> {
    T getData();
    void putData(T stuff);
}

class IntStuff implements Stuff<Integer> {
    private Integer stuff;
    public Integer getData() {
        return stuff;
    }
    public void putData(final Integer stuff) {
        this.stuff = stuff;
    }
}

If you look at the generated bytecode, you will see: In the main method, the erased interface methods

java.lang.Object Stuff.getData()
void Stuff.putData(java.lang.Object)

are invoked. That methods, implemented in IntStuff with the signatures

java.lang.Object getData()
void putData(java.lang.Object)

both with the modifiers public bridge synthetic, delegate to the "real" methods

java.lang.Integer IntStuff.getData()
void putData(java.lang.Integer)

The first synthetic method merely returns the Integer result, while the second performs a cast from Object to Integer before calling putData(Integer).

If you change the stuff variable to type IntStuff, then both Integer methods are called instead of the synthetic Object methods.

like image 96
Christian Semrau Avatar answered Sep 20 '22 05:09

Christian Semrau