You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Jonathan Valliere <jo...@apache.org> on 2018/10/11 16:07:09 UTC
Java Generics
I was having a conversation with a colleague last week about the cost of
automatic casting due to the use of generics in java; so, I decided to
write a benchmark. Since everyone wants their networking code to run as
fast as possible, I thought I would share it with all of you.
Feel free to peer-review the code.
https://github.com/jon-valliere/jmh-generics-benchmark
Re: Java Generics
Posted by Jonathan Valliere <jo...@emoten.com>.
I updated the test suite this morning. There is definitely a correlation
to performance and invokeinterface, however BakedGenericAbstractTest is
using invokevirtual and is actually 2x as expensive as invokeinterface in
that test.
On Fri, Oct 12, 2018 at 4:29 AM Emmanuel Lécharny <el...@gmail.com>
wrote:
>
>
> Le 11/10/2018 à 19:03, Jonathan Valliere a écrit :
> > One explaination I came up was that Java is performing a full upcast when
> > encountering the generic-based interface. Unchecked and checked genetics
> > perform identically.
>
> Here is the bytecode for the strictMethod() :
>
> 0: aload_0
> 1: invokevirtual #12 // Method
> createStrictReceiver:()LSimpleInliningTest$ReceiverB;
> 4: astore_1
> 5: aload_0
> 6: invokevirtual #13 // Method
> createStrictObject:()LSimpleInliningTest$TypeA;
> 9: astore_2
> 10: aconst_null
> 11: astore_3
> 12: iconst_0
> 13: istore 4
> 15: iload 4
> 17: ldc #4 // int 1000000
> 19: if_icmpeq 48
> 22: aload_3
> 23: aload_2
> 24: if_acmpne 36
> 27: aload_1
> 28: aload_2
> 29: invokevirtual #14 // Method
>
> SimpleInliningTest$ReceiverB.foo:(LSimpleInliningTest$TypeA;)LSimpleInliningTest$TypeA;
> 32: astore_3
> 33: goto 42
> 36: aload_1
> 37: aload_2
> 38: invokevirtual #14 // Method
>
> SimpleInliningTest$ReceiverB.foo:(LSimpleInliningTest$TypeA;)LSimpleInliningTest$TypeA;
> 41: astore_3
> 42: iinc 4, 1
> 45: goto 15
> 48: return
>
> and the same for uncheckedMethod():
>
> 0: aload_0
> 1: invokevirtual #2 // Method
> createUncheckedReceiver:()LSimpleInliningTest$Receiver;
> 4: astore_1
> 5: aload_0
> 6: invokevirtual #3 // Method
> createUncheckedObject:()Ljava/lang/Object;
> 9: astore_2
> 10: aconst_null
> 11: astore_3
> 12: iconst_0
> 13: istore 4
> 15: iload 4
> 17: ldc #4 // int 1000000
> 19: if_icmpeq 52
> 22: aload_3
> 23: aload_2
> 24: if_acmpne 38
> 27: aload_1
> 28: aload_2
> 29: invokeinterface #5, 2// InterfaceMethod
> SimpleInliningTest$Receiver.foo:(Ljava/lang/Object;)Ljava/lang/Object;
> 34: astore_3
> 35: goto 46
> 38: aload_1
> 39: aload_2
> 40: invokeinterface #5, 2// InterfaceMethod
> SimpleInliningTest$Receiver.foo:(Ljava/lang/Object;)Ljava/lang/Object;
> 45: astore_3
> 46: iinc 4, 1
> 49: goto 15
> 52: return
>
>
>
> My guess is that the difference coms from the invokevirtual being used
> on one case and invokeinterface in the other (line 29).
>
> invokeinterface seems clearly coslier than invokevirtual.
>
> --
> Emmanuel Lecharny
>
> Symas.com
> directory.apache.org
>
>
Re: Java Generics
Posted by Emmanuel Lécharny <el...@gmail.com>.
Le 11/10/2018 à 19:03, Jonathan Valliere a écrit :
> One explaination I came up was that Java is performing a full upcast when
> encountering the generic-based interface. Unchecked and checked genetics
> perform identically.
Here is the bytecode for the strictMethod() :
0: aload_0
1: invokevirtual #12 // Method
createStrictReceiver:()LSimpleInliningTest$ReceiverB;
4: astore_1
5: aload_0
6: invokevirtual #13 // Method
createStrictObject:()LSimpleInliningTest$TypeA;
9: astore_2
10: aconst_null
11: astore_3
12: iconst_0
13: istore 4
15: iload 4
17: ldc #4 // int 1000000
19: if_icmpeq 48
22: aload_3
23: aload_2
24: if_acmpne 36
27: aload_1
28: aload_2
29: invokevirtual #14 // Method
SimpleInliningTest$ReceiverB.foo:(LSimpleInliningTest$TypeA;)LSimpleInliningTest$TypeA;
32: astore_3
33: goto 42
36: aload_1
37: aload_2
38: invokevirtual #14 // Method
SimpleInliningTest$ReceiverB.foo:(LSimpleInliningTest$TypeA;)LSimpleInliningTest$TypeA;
41: astore_3
42: iinc 4, 1
45: goto 15
48: return
and the same for uncheckedMethod():
0: aload_0
1: invokevirtual #2 // Method
createUncheckedReceiver:()LSimpleInliningTest$Receiver;
4: astore_1
5: aload_0
6: invokevirtual #3 // Method
createUncheckedObject:()Ljava/lang/Object;
9: astore_2
10: aconst_null
11: astore_3
12: iconst_0
13: istore 4
15: iload 4
17: ldc #4 // int 1000000
19: if_icmpeq 52
22: aload_3
23: aload_2
24: if_acmpne 38
27: aload_1
28: aload_2
29: invokeinterface #5, 2// InterfaceMethod
SimpleInliningTest$Receiver.foo:(Ljava/lang/Object;)Ljava/lang/Object;
34: astore_3
35: goto 46
38: aload_1
39: aload_2
40: invokeinterface #5, 2// InterfaceMethod
SimpleInliningTest$Receiver.foo:(Ljava/lang/Object;)Ljava/lang/Object;
45: astore_3
46: iinc 4, 1
49: goto 15
52: return
My guess is that the difference coms from the invokevirtual being used
on one case and invokeinterface in the other (line 29).
invokeinterface seems clearly coslier than invokevirtual.
--
Emmanuel Lecharny
Symas.com
directory.apache.org
Re: Java Generics
Posted by Jonathan Valliere <jo...@emoten.com>.
One explaination I came up was that Java is performing a full upcast when
encountering the generic-based interface. Unchecked and checked genetics
perform identically.
Because the generics are fully removed at compile time; Java may be forced
to do full type casting every time the method is called.
If there isn’t something inherently wrong with the test then there is a big
performance penalty when using generic interfaces.
On Thu, Oct 11, 2018 at 12:50 PM Emmanuel Lécharny <el...@gmail.com>
wrote:
> Thanks, Jonathan,
>
> Le 11/10/2018 à 18:07, Jonathan Valliere a écrit :
> > I was having a conversation with a colleague last week about the cost of
> > automatic casting due to the use of generics in java; so, I decided to
> > write a benchmark. Since everyone wants their networking code to run as
> > fast as possible, I thought I would share it with all of you.
> >
> > Feel free to peer-review the code.
> > https://github.com/jon-valliere/jmh-generics-benchmark
>
> Running this benchmark, I get a 10x slower run when using generic
> compared to the non-generic version (3G op/s vs 300M op/s)
>
> That beaing said, Generic are't supposed to have any impact on java
> code, because it's all removed by the compiler, so there must be
> something weirdo going on. It would be interesting to check the
> generated bytecode to see the difference.
>
>
> --
> Emmanuel Lecharny
>
> Symas.com
> directory.apache.org
>
>
Re: Java Generics
Posted by Emmanuel Lécharny <el...@gmail.com>.
Thanks, Jonathan,
Le 11/10/2018 à 18:07, Jonathan Valliere a écrit :
> I was having a conversation with a colleague last week about the cost of
> automatic casting due to the use of generics in java; so, I decided to
> write a benchmark. Since everyone wants their networking code to run as
> fast as possible, I thought I would share it with all of you.
>
> Feel free to peer-review the code.
> https://github.com/jon-valliere/jmh-generics-benchmark
Running this benchmark, I get a 10x slower run when using generic
compared to the non-generic version (3G op/s vs 300M op/s)
That beaing said, Generic are't supposed to have any impact on java
code, because it's all removed by the compiler, so there must be
something weirdo going on. It would be interesting to check the
generated bytecode to see the difference.
--
Emmanuel Lecharny
Symas.com
directory.apache.org