Re: Which optimizations does Hotspot apply?
Hi Rémi, With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). Could you please explain it a little bit more? When is that optimization applied, e.g. what conditions are required for this optimization, since which version of JDK/Hotspot it is supported, where it is implemented in JDK? When I take look at a product I'm working on, I see a lot instances of ArrayList$Itr objects, which are created by for-each loops (we use JDK 7u51). Thanks in advance! Best regards, Andrej Golovnin
Re: Which optimizations does Hotspot apply?
Hotspot questions belong on hotspot lists. cc'ing hotspot-dev and (trying to) bcc core-libs-dev. David On 23/01/2014 9:37 AM, Remi Forax wrote: On 01/22/2014 11:37 PM, Robert Stupp wrote: Is there any documentation available which optimizations Hotspot can perform and what collecting a garbage object costs? I know that these are two completely different areas ;) I was inspecting whether the following code for (Object o : someArrayList) { ... } would be faster than for (int i=0, l=someArrayList.size(); il; i++) { Object o=someArrayList.get(i); } for RandomAccessList implementations. The challenge here is not just to track the CPU time spent creating using the iterator vs. size() get() calls but also track GC effort (which is at least complicated if not impossible due to the variety of GC configuration options). For a long time, using a for with an index (if you are *sure* that it's an ArrayList) was faster. With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). For example: - Does it help Hotspot to declare parameters/variables as final or can Hotspot identify that? no, it's an urban myth. You can test it by yourself, if you declare a local variable final or not the exact same bytecode is produced by javac. The keyword final for a local variable (or a parameter) is not stored in the bytecode. BTW, final was introduced in 1.1 mostly to allow to capture the value of a variable to be used by an anonymous class, Java 8 doesn't require this kind of variable to be declared final anymore. - When does Hotspot inline method calls in general and getters/setters especially? In general, up to a depth of 10 by default and 1 for a recursive method. Roughly, a method call is not inlined either if the call is virtual and can call too many implementations or if the generated assembly code will be too big. I think such a piece of documentation (just what Hotspot can do in which release) would be really helpful when someone tries to optimize code - want to say: the question is: Is something worth to spend time on or is this special situation handled by Hotspot? It never worth it. Choose the right algorithms and shape your data to be easily consumed by your algorithms is enough. -Robert Rémi
Re: Which optimizations does Hotspot apply?
Hi Rémi, Vitaly, Thank you for your explanation and for the tips! if you see a lot of instances of ArrayList iterator it means that you have a code path that create an iterator and use it later and the JIT is not able to see the creation and the use in the same inlining horizon. As Vitaly said, it's perhaps because you have the same code called with several different kinds of List (teach your programmer to stop to use LinkedList :) or because the code create an Iterator too far from where you use it (by example if the iterator is stored in a List or a Map). I fight the LinkedList all the time. :-) Cheers, Andrej
Re: Which optimizations does Hotspot apply?
On 01/23/2014 01:39 AM, Vitaly Davidovich wrote: Remi, Regarding your last point - picking correct data structures and algos is of course step 1 in any optimization. No, step 1 is to be sure that your problem is CPU bound. But, provided that's taken care of, there're plausible reasons to attempt to cater to hotspot as well (if that's the jvm in use). There are certainly code shapes that it prefers. yes, any JITs have preferred code shapes. The thing is that to know if a new optimization will be included, the perf tests will be done using benchmarks that usually use dumb codes, as a logical consequence JITs are trained to recognize dumb codes. That's why trying to do any micro-optimization using 'smart' code shape usually result in a code that is slower. There's a whole slew of inlining heuristics and rules to be aware of. Those rules change. There's a set of intrinsics, in some cases covering only a subset of an API of a class. These things are always subject to change, but saying never worth it isn't right either :). yes, yo're right it's not right, let say it almost right :) Rémi Sent from my phone On Jan 22, 2014 6:38 PM, Remi Forax fo...@univ-mlv.fr mailto:fo...@univ-mlv.fr wrote: On 01/22/2014 11:37 PM, Robert Stupp wrote: Is there any documentation available which optimizations Hotspot can perform and what collecting a garbage object costs? I know that these are two completely different areas ;) I was inspecting whether the following code for (Object o : someArrayList) { ... } would be faster than for (int i=0, l=someArrayList.size(); il; i++) { Object o=someArrayList.get(i); } for RandomAccessList implementations. The challenge here is not just to track the CPU time spent creating using the iterator vs. size() get() calls but also track GC effort (which is at least complicated if not impossible due to the variety of GC configuration options). For a long time, using a for with an index (if you are *sure* that it's an ArrayList) was faster. With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). For example: - Does it help Hotspot to declare parameters/variables as final or can Hotspot identify that? no, it's an urban myth. You can test it by yourself, if you declare a local variable final or not the exact same bytecode is produced by javac. The keyword final for a local variable (or a parameter) is not stored in the bytecode. BTW, final was introduced in 1.1 mostly to allow to capture the value of a variable to be used by an anonymous class, Java 8 doesn't require this kind of variable to be declared final anymore. - When does Hotspot inline method calls in general and getters/setters especially? In general, up to a depth of 10 by default and 1 for a recursive method. Roughly, a method call is not inlined either if the call is virtual and can call too many implementations or if the generated assembly code will be too big. I think such a piece of documentation (just what Hotspot can do in which release) would be really helpful when someone tries to optimize code - want to say: the question is: Is something worth to spend time on or is this special situation handled by Hotspot? It never worth it. Choose the right algorithms and shape your data to be easily consumed by your algorithms is enough. -Robert Rémi
Re: Which optimizations does Hotspot apply?
On 01/24/2014 11:01 PM, Vitaly Davidovich wrote: This would be predicated on escape analysis, whose effectiveness is in turn driven by sufficient inlining whereby compiler can see that instance doesn't escape. Inlining, in turn, can be screwed up by (amongst other things) polymorphic call sites. So in the end, it's all quite brittle and sensitive :). Personally, in places where it matters, I try to allocate as little as possible explicitly - a lot of times much more effective than hoping compiler helps out and/or turning GC knobs. Sent from my phone Hi Andrej, if you see a lot of instances of ArrayList iterator it means that you have a code path that create an iterator and use it later and the JIT is not able to see the creation and the use in the same inlining horizon. As Vitaly said, it's perhaps because you have the same code called with several different kinds of List (teach your programmer to stop to use LinkedList :) or because the code create an Iterator too far from where you use it (by example if the iterator is stored in a List or a Map). If you use -XX:+PrintInlining, the VM will print the reason why something is not inlined. cheers, Rémi On Jan 24, 2014 4:36 PM, Andrej Golovnin golov...@gmx.net wrote: Hi Rémi, With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). Could you please explain it a little bit more? When is that optimization applied, e.g. what conditions are required for this optimization, since which version of JDK/Hotspot it is supported, where it is implemented in JDK? When I take look at a product I'm working on, I see a lot instances of ArrayList$Itr objects, which are created by for-each loops (we use JDK 7u51). Thanks in advance! Best regards, Andrej Golovnin
Re: Which optimizations does Hotspot apply?
One thing that would be very useful (and I've asked Vladimir Kozlov for it) is to expose a product flag (I believe there's one now but it's develop) to trace EA decisions/reasons. Maybe that's already planned, but if not, hopefully it makes it at some point. Sent from my phone On Jan 25, 2014 5:15 AM, Remi Forax fo...@univ-mlv.fr wrote: On 01/24/2014 11:01 PM, Vitaly Davidovich wrote: This would be predicated on escape analysis, whose effectiveness is in turn driven by sufficient inlining whereby compiler can see that instance doesn't escape. Inlining, in turn, can be screwed up by (amongst other things) polymorphic call sites. So in the end, it's all quite brittle and sensitive :). Personally, in places where it matters, I try to allocate as little as possible explicitly - a lot of times much more effective than hoping compiler helps out and/or turning GC knobs. Sent from my phone Hi Andrej, if you see a lot of instances of ArrayList iterator it means that you have a code path that create an iterator and use it later and the JIT is not able to see the creation and the use in the same inlining horizon. As Vitaly said, it's perhaps because you have the same code called with several different kinds of List (teach your programmer to stop to use LinkedList :) or because the code create an Iterator too far from where you use it (by example if the iterator is stored in a List or a Map). If you use -XX:+PrintInlining, the VM will print the reason why something is not inlined. cheers, Rémi On Jan 24, 2014 4:36 PM, Andrej Golovnin golov...@gmx.net wrote: Hi Rémi, With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). Could you please explain it a little bit more? When is that optimization applied, e.g. what conditions are required for this optimization, since which version of JDK/Hotspot it is supported, where it is implemented in JDK? When I take look at a product I'm working on, I see a lot instances of ArrayList$Itr objects, which are created by for-each loops (we use JDK 7u51). Thanks in advance! Best regards, Andrej Golovnin
Re: Which optimizations does Hotspot apply?
Hi Rémi, With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). Could you please explain it a little bit more? When is that optimization applied, e.g. what conditions are required for this optimization, since which version of JDK/Hotspot it is supported, where it is implemented in JDK? When I take look at a product I'm working on, I see a lot instances of ArrayList$Itr objects, which are created by for-each loops (we use JDK 7u51). Thanks in advance! Best regards, Andrej Golovnin
Re: Which optimizations does Hotspot apply?
This would be predicated on escape analysis, whose effectiveness is in turn driven by sufficient inlining whereby compiler can see that instance doesn't escape. Inlining, in turn, can be screwed up by (amongst other things) polymorphic call sites. So in the end, it's all quite brittle and sensitive :). Personally, in places where it matters, I try to allocate as little as possible explicitly - a lot of times much more effective than hoping compiler helps out and/or turning GC knobs. Sent from my phone On Jan 24, 2014 4:36 PM, Andrej Golovnin golov...@gmx.net wrote: Hi Rémi, With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). Could you please explain it a little bit more? When is that optimization applied, e.g. what conditions are required for this optimization, since which version of JDK/Hotspot it is supported, where it is implemented in JDK? When I take look at a product I'm working on, I see a lot instances of ArrayList$Itr objects, which are created by for-each loops (we use JDK 7u51). Thanks in advance! Best regards, Andrej Golovnin
Which optimizations does Hotspot apply?
Is there any documentation available which optimizations Hotspot can perform and what collecting a garbage object costs? I know that these are two completely different areas ;) I was inspecting whether the following code for (Object o : someArrayList) { ... } would be faster than for (int i=0, l=someArrayList.size(); il; i++) { Object o=someArrayList.get(i); } for RandomAccessList implementations. The challenge here is not just to track the CPU time spent creating using the iterator vs. size() get() calls but also track GC effort (which is at least complicated if not impossible due to the variety of GC configuration options). For example: - Does it help Hotspot to declare parameters/variables as final or can Hotspot identify that? - When does Hotspot inline method calls in general and getters/setters especially? I think such a piece of documentation (just what Hotspot can do in which release) would be really helpful when someone tries to optimize code - want to say: the question is: Is something worth to spend time on or is this special situation handled by Hotspot? -Robert
Re: Which optimizations does Hotspot apply?
You can start here: wikis.oracle.com/display/hotspotinternals/performancetechniques Sent from my phone On Jan 22, 2014 5:37 PM, Robert Stupp sn...@snazy.de wrote: Is there any documentation available which optimizations Hotspot can perform and what collecting a garbage object costs? I know that these are two completely different areas ;) I was inspecting whether the following code for (Object o : someArrayList) { ... } would be faster than for (int i=0, l=someArrayList.size(); il; i++) { Object o=someArrayList.get(i); } for RandomAccessList implementations. The challenge here is not just to track the CPU time spent creating using the iterator vs. size() get() calls but also track GC effort (which is at least complicated if not impossible due to the variety of GC configuration options). For example: - Does it help Hotspot to declare parameters/variables as final or can Hotspot identify that? - When does Hotspot inline method calls in general and getters/setters especially? I think such a piece of documentation (just what Hotspot can do in which release) would be really helpful when someone tries to optimize code - want to say: the question is: Is something worth to spend time on or is this special situation handled by Hotspot? -Robert
Re: Which optimizations does Hotspot apply?
Remi, Regarding your last point - picking correct data structures and algos is of course step 1 in any optimization. But, provided that's taken care of, there're plausible reasons to attempt to cater to hotspot as well (if that's the jvm in use). There are certainly code shapes that it prefers. There's a whole slew of inlining heuristics and rules to be aware of. There's a set of intrinsics, in some cases covering only a subset of an API of a class. These things are always subject to change, but saying never worth it isn't right either :). Sent from my phone On Jan 22, 2014 6:38 PM, Remi Forax fo...@univ-mlv.fr wrote: On 01/22/2014 11:37 PM, Robert Stupp wrote: Is there any documentation available which optimizations Hotspot can perform and what collecting a garbage object costs? I know that these are two completely different areas ;) I was inspecting whether the following code for (Object o : someArrayList) { ... } would be faster than for (int i=0, l=someArrayList.size(); il; i++) { Object o=someArrayList.get(i); } for RandomAccessList implementations. The challenge here is not just to track the CPU time spent creating using the iterator vs. size() get() calls but also track GC effort (which is at least complicated if not impossible due to the variety of GC configuration options). For a long time, using a for with an index (if you are *sure* that it's an ArrayList) was faster. With latest jdk8, it's not true anymore. (and most of the time the iterator object is not created anymore at least with jdk7+). For example: - Does it help Hotspot to declare parameters/variables as final or can Hotspot identify that? no, it's an urban myth. You can test it by yourself, if you declare a local variable final or not the exact same bytecode is produced by javac. The keyword final for a local variable (or a parameter) is not stored in the bytecode. BTW, final was introduced in 1.1 mostly to allow to capture the value of a variable to be used by an anonymous class, Java 8 doesn't require this kind of variable to be declared final anymore. - When does Hotspot inline method calls in general and getters/setters especially? In general, up to a depth of 10 by default and 1 for a recursive method. Roughly, a method call is not inlined either if the call is virtual and can call too many implementations or if the generated assembly code will be too big. I think such a piece of documentation (just what Hotspot can do in which release) would be really helpful when someone tries to optimize code - want to say: the question is: Is something worth to spend time on or is this special situation handled by Hotspot? It never worth it. Choose the right algorithms and shape your data to be easily consumed by your algorithms is enough. -Robert Rémi