{"id":275,"date":"2011-06-10T20:56:16","date_gmt":"2011-06-10T20:56:16","guid":{"rendered":"https:\/\/kari.world.ikari.fi\/2011\/06\/10\/eeny-weeny-nitpicking-peeny\/"},"modified":"2011-06-10T20:56:16","modified_gmt":"2011-06-10T20:56:16","slug":"eeny-weeny-nitpicking-peeny","status":"publish","type":"post","link":"https:\/\/kari.world.ikari.fi\/?p=275","title":{"rendered":"Eeny, weeny, nitpicking, peeny"},"content":{"rendered":"<p>Todays lesson is: What <code>javac<\/code> does with following methods, when compiled.<\/p>\n<p><b>Assumptions:<\/b><\/p>\n<ul>\n<li>Iterating over ArrayList vs. List generates optimized code, not creating Iterator (i.e. would optimize memory usage using <code>RandomAccessList<\/code> API), but using int index<\/li>\n<li>Itearating over Object[] is faster than <code>List\/ArrayList<\/code><\/li>\n<li>foreach loop for Object[] is as tight code as manual iteration<\/li>\n<\/ul>\n<p>[code lang=&#8221;java&#8221;]<br \/>\nclass OptimizedLoop {<\/p>\n<p>  void doLoop1_1(List pList) {<br \/>\n    for (Object value : pList) {<br \/>\n      System.out.println(value.toString());<br \/>\n    }<br \/>\n  }<\/p>\n<p>  void doLoop1_2(ArrayList pList) {<br \/>\n    for (Object value : pList) {<br \/>\n      System.out.println(value.toString());<br \/>\n    }<br \/>\n  }<\/p>\n<p>  void doLoop1_3(List pList) {<br \/>\n    for (int i = 0; i < pList.size(); i++) {\n      System.out.println(pList.get(i).toString());\n    }\n  }\n\n  void doLoop1_4(List pList) {\n    for (int i = pList.size() - 1; i >= 0; i&#8211;) {<br \/>\n      System.out.println(pList.get(i).toString());<br \/>\n    }<br \/>\n  }<\/p>\n<p>  void doLoop2_1(Object[] pList) {<br \/>\n    for (Object value : pList) {<br \/>\n      System.out.println(value.toString());<br \/>\n    }<br \/>\n  }<\/p>\n<p>  void doLoop2_2(Object[] pList) {<br \/>\n    for (int i = 0; i < pList.length; i++) {\n      System.out.println(pList[i].toString());\n    }\n  }\n\n  void doLoop2_3(Object[] pList) {\n    for (int i = pList.length- 1; i >= 0; i&#8211;) {<br \/>\n      System.out.println(pList[i].toString());<br \/>\n    }<br \/>\n  }<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>And here are the results,<\/p>\n<p>[code lang=&#8221;java&#8221;]<br \/>\nclass OptimizedLoop {<br \/>\n  OptimizedLoop();<br \/>\n    Code:<br \/>\n       0: aload_0<br \/>\n       1: invokespecial #1                  \/\/ Method java\/lang\/Object.&#8221;<init>&#8221;:()V<br \/>\n       4: return<\/p>\n<p>  void doLoop1_1(java.util.List);<br \/>\n    Code:<br \/>\n       0: aload_1<br \/>\n       1: invokeinterface #2,  1            \/\/ InterfaceMethod java\/util\/List.iterator:()Ljava\/util\/Iterator;<br \/>\n       6: astore_2<br \/>\n       7: aload_2<br \/>\n       8: invokeinterface #3,  1            \/\/ InterfaceMethod java\/util\/Iterator.hasNext:()Z<br \/>\n      13: ifeq          36<br \/>\n      16: aload_2<br \/>\n      17: invokeinterface #4,  1            \/\/ InterfaceMethod java\/util\/Iterator.next:()Ljava\/lang\/Object;<br \/>\n      22: astore_3<br \/>\n      23: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      26: aload_3<br \/>\n      27: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      30: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      33: goto          7<br \/>\n      36: return<\/p>\n<p>  void doLoop1_2(java.util.ArrayList);<br \/>\n    Code:<br \/>\n       0: aload_1<br \/>\n       1: invokevirtual #8                  \/\/ Method java\/util\/ArrayList.iterator:()Ljava\/util\/Iterator;<br \/>\n       4: astore_2<br \/>\n       5: aload_2<br \/>\n       6: invokeinterface #3,  1            \/\/ InterfaceMethod java\/util\/Iterator.hasNext:()Z<br \/>\n      11: ifeq          34<br \/>\n      14: aload_2<br \/>\n      15: invokeinterface #4,  1            \/\/ InterfaceMethod java\/util\/Iterator.next:()Ljava\/lang\/Object;<br \/>\n      20: astore_3<br \/>\n      21: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      24: aload_3<br \/>\n      25: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      28: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      31: goto          5<br \/>\n      34: return<\/p>\n<p>  void doLoop1_3(java.util.List);<br \/>\n    Code:<br \/>\n       0: iconst_0<br \/>\n       1: istore_2<br \/>\n       2: iload_2<br \/>\n       3: aload_1<br \/>\n       4: invokeinterface #9,  1            \/\/ InterfaceMethod java\/util\/List.size:()I<br \/>\n       9: if_icmpge     34<br \/>\n      12: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      15: aload_1<br \/>\n      16: iload_2<br \/>\n      17: invokeinterface #10,  2           \/\/ InterfaceMethod java\/util\/List.get:(I)Ljava\/lang\/Object;<br \/>\n      22: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      25: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      28: iinc          2, 1<br \/>\n      31: goto          2<br \/>\n      34: return<\/p>\n<p>  void doLoop1_4(java.util.List);<br \/>\n    Code:<br \/>\n       0: aload_1<br \/>\n       1: invokeinterface #9,  1            \/\/ InterfaceMethod java\/util\/List.size:()I<br \/>\n       6: iconst_1<br \/>\n       7: isub<br \/>\n       8: istore_2<br \/>\n       9: iload_2<br \/>\n      10: iflt          35<br \/>\n      13: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      16: aload_1<br \/>\n      17: iload_2<br \/>\n      18: invokeinterface #10,  2           \/\/ InterfaceMethod java\/util\/List.get:(I)Ljava\/lang\/Object;<br \/>\n      23: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      26: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      29: iinc          2, -1<br \/>\n      32: goto          9<br \/>\n      35: return<\/p>\n<p>  void doLoop2_1(java.lang.Object[]);<br \/>\n    Code:<br \/>\n       0: aload_1<br \/>\n       1: astore_2<br \/>\n       2: aload_2<br \/>\n       3: arraylength<br \/>\n       4: istore_3<br \/>\n       5: iconst_0<br \/>\n       6: istore        4<br \/>\n       8: iload         4<br \/>\n      10: iload_3<br \/>\n      11: if_icmpge     37<br \/>\n      14: aload_2<br \/>\n      15: iload         4<br \/>\n      17: aaload<br \/>\n      18: astore        5<br \/>\n      20: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      23: aload         5<br \/>\n      25: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      28: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      31: iinc          4, 1<br \/>\n      34: goto          8<br \/>\n      37: return<\/p>\n<p>  void doLoop2_2(java.lang.Object[]);<br \/>\n    Code:<br \/>\n       0: iconst_0<br \/>\n       1: istore_2<br \/>\n       2: iload_2<br \/>\n       3: aload_1<br \/>\n       4: arraylength<br \/>\n       5: if_icmpge     26<br \/>\n       8: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      11: aload_1<br \/>\n      12: iload_2<br \/>\n      13: aaload<br \/>\n      14: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      17: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      20: iinc          2, 1<br \/>\n      23: goto          2<br \/>\n      26: return<\/p>\n<p>  void doLoop2_3(java.lang.Object[]);<br \/>\n    Code:<br \/>\n       0: aload_1<br \/>\n       1: arraylength<br \/>\n       2: iconst_1<br \/>\n       3: isub<br \/>\n       4: istore_2<br \/>\n       5: iload_2<br \/>\n       6: iflt          27<br \/>\n       9: getstatic     #5                  \/\/ Field java\/lang\/System.out:Ljava\/io\/PrintStream;<br \/>\n      12: aload_1<br \/>\n      13: iload_2<br \/>\n      14: aaload<br \/>\n      15: invokevirtual #6                  \/\/ Method java\/lang\/Object.toString:()Ljava\/lang\/String;<br \/>\n      18: invokevirtual #7                  \/\/ Method java\/io\/PrintStream.println:(Ljava\/lang\/String;)V<br \/>\n      21: iinc          2, -1<br \/>\n      24: goto          5<br \/>\n      27: return<br \/>\n}<br \/>\n[\/code]<\/p>\n<p><b>Failed assumptions:<\/b><\/p>\n<ul>\n<li><code>RandomAccessList<\/code> didn&#8217;t help, thus it&#8217;s still preferable to <a href=\"https:\/\/kari.world.ikari.fi\/2011\/06\/02\/premature-optimization-chapter-class-is-the-root-of-all-evil\/\">prefer interfaces<\/a><\/li>\n<li>foreach loop for Object[] doesn&#8217;t match manual iteration, so there is still reasons to do it your way<\/li>\n<\/ul>\n<p><b>References:<\/b><br \/>\n<a href=\"http:\/\/today.java.net\/article\/2006\/11\/03\/nuances-java-50-each-loop\">Nuances of the Java 5.0 for-each Loop<\/a><br \/>\n<a href=\"https:\/\/kari.world.ikari.fi\/2011\/06\/02\/premature-optimization-chapter-class-is-the-root-of-all-evil\/\">Kari&#8217;s World: Premature Optimization: Chapter \u201cClass is the root of all evil\u201d<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Todays lesson is: What javac does with following methods, when compiled. Assumptions: Iterating over ArrayList vs. List generates optimized code, not creating Iterator (i.e. would optimize memory usage using RandomAccessList API), but using int index Itearating over Object[] is faster than List\/ArrayList foreach loop for Object[] is as tight code as manual iteration [code lang=&#8221;java&#8221;]&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-275","post","type-post","status-publish","format-standard","hentry","category-java"],"_links":{"self":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts\/275","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=275"}],"version-history":[{"count":0,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts\/275\/revisions"}],"wp:attachment":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}