{"id":276,"date":"2011-06-10T21:13:18","date_gmt":"2011-06-10T21:13:18","guid":{"rendered":"https:\/\/kari.world.ikari.fi\/2011\/06\/10\/speculate-but-dont-guess-measure-to-see\/"},"modified":"2011-06-10T21:13:18","modified_gmt":"2011-06-10T21:13:18","slug":"speculate-but-dont-guess-measure-to-see","status":"publish","type":"post","link":"https:\/\/kari.world.ikari.fi\/?p=276","title":{"rendered":"Speculate, but don&#8217;t guess, measure to see"},"content":{"rendered":"<p>How <code>synchronized<\/code> keyword behaves in methods. I&#8217;ve heard speculation that <code>doFoo1()<\/code> would result into more compact byte code, but I don&#8217;t buy that.<\/p>\n<p><b>Assumption:<\/b><br \/>\nByte code in both cases, is same.<\/p>\n<p>So we have this sample,<\/p>\n<p>[code lang=&#8221;java&#8221;]<br \/>\nclass SyncMe {<\/p>\n<p> synchronized void doFoo1() {<br \/>\n    int x = 0;<br \/>\n }<\/p>\n<p> void doFoo2() {<br \/>\n    synchronized (this) {<br \/>\n      int x = 0;<br \/>\n    }<br \/>\n }<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>And the result is, <code>javap -c SyncMe<\/code><\/p>\n<p>[code lang=&#8221;java&#8221;]<br \/>\nclass SyncMe {<br \/>\n  SyncMe();<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>  synchronized void doFoo1();<br \/>\n    Code:<br \/>\n       0: iconst_0<br \/>\n       1: istore_1<br \/>\n       2: return<\/p>\n<p>  void doFoo2();<br \/>\n    Code:<br \/>\n       0: aload_0<br \/>\n       1: dup<br \/>\n       2: astore_1<br \/>\n       3: monitorenter<br \/>\n       4: iconst_0<br \/>\n       5: istore_2<br \/>\n       6: aload_1<br \/>\n       7: monitorexit<br \/>\n       8: goto          16<br \/>\n      11: astore_3<br \/>\n      12: aload_1<br \/>\n      13: monitorexit<br \/>\n      14: aload_3<br \/>\n      15: athrow<br \/>\n      16: return<br \/>\n    Exception table:<br \/>\n       from    to  target type<br \/>\n           4     8    11   any<br \/>\n          11    14    11   any<br \/>\n}<br \/>\n[\/code]<\/p>\n<p><b>Result:<\/b><br \/>\nHowly cotton ball. They really <b>ARE<\/b> different. Based on this is more adviceable to use <code>synchronized<\/code> keyword in method, than adding blocks manually inside the method.<\/p>\n<p><b>TIP:<\/b><br \/>\nSo how you do that, in practise. Answer is simple, use good approach of using <b>small<\/b> methods.<\/p>\n<p>[code lang=&#8221;java&#8221;]<br \/>\nclass SyncProper {<br \/>\n int x;<\/p>\n<p> synchronized void resetX() {<br \/>\n    x = 0;<br \/>\n }<\/p>\n<p> void doGood() {<br \/>\n    \/\/ do stuff<br \/>\n    resetX();<br \/>\n    \/\/ do more stuff<br \/>\n }<\/p>\n<p> void doBad() {<br \/>\n    \/\/ do stuff<br \/>\n    synchronized (this) {<br \/>\n      x = 0;<br \/>\n    }<br \/>\n    \/\/ do more stuff<br \/>\n }<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>And as simple as that, simple and clean code, relying good programming patterns, leads into best optimized code.<\/p>\n<p>[code lang=&#8221;java&#8221;]<br \/>\nclass SyncProper {<br \/>\n  int x;<\/p>\n<p>  SyncProper();<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>  synchronized void resetX();<br \/>\n    Code:<br \/>\n       0: aload_0<br \/>\n       1: iconst_0<br \/>\n       2: putfield      #2                  \/\/ Field x:I<br \/>\n       5: return<\/p>\n<p>  void doGood();<br \/>\n    Code:<br \/>\n       0: aload_0<br \/>\n       1: invokevirtual #3                  \/\/ Method resetX:()V<br \/>\n       4: return<\/p>\n<p>  void doBad();<br \/>\n    Code:<br \/>\n       0: aload_0<br \/>\n       1: dup<br \/>\n       2: astore_1<br \/>\n       3: monitorenter<br \/>\n       4: aload_0<br \/>\n       5: iconst_0<br \/>\n       6: putfield      #2                  \/\/ Field x:I<br \/>\n       9: aload_1<br \/>\n      10: monitorexit<br \/>\n      11: goto          19<br \/>\n      14: astore_2<br \/>\n      15: aload_1<br \/>\n      16: monitorexit<br \/>\n      17: aload_2<br \/>\n      18: athrow<br \/>\n      19: return<br \/>\n    Exception table:<br \/>\n       from    to  target type<br \/>\n           4    11    14   any<br \/>\n          14    17    14   any<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>As class file size, doing it good way, resulted into class file of size <b>344<\/b> bytes, and using bad way resulted <b>390<\/b> bytes. Naturally those were measure by using exactly same length class\/field\/method names to avoid variance due to that. Notice, however, that good way has one extra method (<code>resetX()<\/code>), but it still manages to be much smaller. Do you still need more proof to prefer small maintainable methods? If you code in the manner what JVM likes, you will make code more clean, and very likely also faster, since, for example, in this case code for managing <code>synchronized<\/code> is externalized into native code (well, I&#8217;m guessing here) or at least closer to JIT\/JVM machine.<\/p>\n<p>So follow da-leader, and <b>doGood()<\/b>. Don&#8217;t speculate, trust the results.<\/p>\n<p><b>References:<\/b><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/4394976\/what-is-the-difference-between-synchronizedthis-and-synchronized-method\">Stackoverlow: What is the difference between synchronized(this) and synchronized method<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/574240\/synchronized-block-vs-synchronized-method\">Stackoverflow: synchronized block vs synchronized method?<\/a><br \/>\n<a href=\"http:\/\/www.ibm.com\/developerworks\/ibm\/library\/it-haggar_bytecode\/\">IBM developerWorks: Java bytecode: Understanding bytecode makes you a better programmer<\/a><br \/>\n<a href=\"http:\/\/arhipov.blogspot.com\/2011\/01\/java-bytecode-fundamentals.html\">Code Impossible: Java Bytecode Fundamentals<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How synchronized keyword behaves in methods. I&#8217;ve heard speculation that doFoo1() would result into more compact byte code, but I don&#8217;t buy that. Assumption: Byte code in both cases, is same. So we have this sample, [code lang=&#8221;java&#8221;] class SyncMe { synchronized void doFoo1() { int x = 0; } void doFoo2() { synchronized (this)&#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-276","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\/276","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=276"}],"version-history":[{"count":0,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts\/276\/revisions"}],"wp:attachment":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=276"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=276"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}