<!-- 
RSS generated by JIRA (4.4#649-r158309) at Wed Jun 19 12:25:27 CDT 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://dev.clojure.org/jira/si/jira.issueviews:issue-xml/CLJ-740/CLJ-740.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>Clojure JIRA</title>
    <link>http://dev.clojure.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>4.4</version>
        <build-number>649</build-number>
        <build-date>25-07-2011</build-date>
    </build-info>

<item>
            <title>[CLJ-740] Unnecessary boxing of primitives in case form</title>
                <link>http://dev.clojure.org/jira/browse/CLJ-740</link>
                <project id="10010" key="CLJ">Clojure</project>
                        <description>&lt;p&gt;Found this while profiling some performance-critical code.&lt;/p&gt;

&lt;p&gt;Consider the following Clojure function:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;(defn test-&lt;span class=&quot;code-keyword&quot;&gt;case&lt;/span&gt; ^&lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt; [^&lt;span class=&quot;code-object&quot;&gt;long&lt;/span&gt; i ^&lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt; d1 ^&lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt; d2]
  (&lt;span class=&quot;code-keyword&quot;&gt;case&lt;/span&gt; (&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt; i)
    0 d1
    d2))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Current Clojure 1.3 snapshot compiles it to:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;&lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt; invokePrim(&lt;span class=&quot;code-object&quot;&gt;long&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt;)   &lt;span class=&quot;code-keyword&quot;&gt;throws&lt;/span&gt; java.lang.Exception;
  Code:
   0:	lload_1
   1:	invokestatic	#67; &lt;span class=&quot;code-comment&quot;&gt;//Method clojure/lang/RT.intCast:(J)I
&lt;/span&gt;   4:	istore	7
   6:	iload	7
   8:	i2l
   9:	invokestatic	#73; &lt;span class=&quot;code-comment&quot;&gt;//Method clojure/lang/Numbers.num:(J)Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Number&lt;/span&gt;;
&lt;/span&gt;   12:	invokestatic	#79; &lt;span class=&quot;code-comment&quot;&gt;//Method clojure/lang/Util.hash:(Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;;)I
&lt;/span&gt;   15:	iconst_0
   16:	ishr
   17:	iconst_1
   18:	iand
   19:	tableswitch{ &lt;span class=&quot;code-comment&quot;&gt;//0 to 0
&lt;/span&gt;		0: 36;
		&lt;span class=&quot;code-keyword&quot;&gt;default&lt;/span&gt;: 58 }
   36:	iload	7
   38:	i2l
   39:	invokestatic	#73; &lt;span class=&quot;code-comment&quot;&gt;//Method clojure/lang/Numbers.num:(J)Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Number&lt;/span&gt;;
&lt;/span&gt;   42:	getstatic	#45; &lt;span class=&quot;code-comment&quot;&gt;//Field const__3:Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;;
&lt;/span&gt;   45:	invokestatic	#83; &lt;span class=&quot;code-comment&quot;&gt;//Method clojure/lang/Util.equals:(Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;;Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;;)Z
&lt;/span&gt;   48:	ifeq	58
   51:	dload_3
   52:	invokestatic	#88; &lt;span class=&quot;code-comment&quot;&gt;//Method java/lang/&lt;span class=&quot;code-object&quot;&gt;Double&lt;/span&gt;.valueOf:(D)Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Double&lt;/span&gt;;
&lt;/span&gt;   55:	&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt;	63
   58:	dload	5
   60:	invokestatic	#88; &lt;span class=&quot;code-comment&quot;&gt;//Method java/lang/&lt;span class=&quot;code-object&quot;&gt;Double&lt;/span&gt;.valueOf:(D)Ljava/lang/&lt;span class=&quot;code-object&quot;&gt;Double&lt;/span&gt;;
&lt;/span&gt;   63:	checkcast	#92; &lt;span class=&quot;code-comment&quot;&gt;//class java/lang/&lt;span class=&quot;code-object&quot;&gt;Number&lt;/span&gt;
&lt;/span&gt;   66:	invokevirtual	#96; &lt;span class=&quot;code-comment&quot;&gt;//Method java/lang/&lt;span class=&quot;code-object&quot;&gt;Number&lt;/span&gt;.doubleValue:()D
&lt;/span&gt;   69:	dreturn
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This bytecode contains boxing of primitives (calls to clojure/lang/Numbers.num and java/lang/Double.valueOf) and calls to clojure/lang/Util.hash and clojure/lang/Util.equals that does not seem necessary.&lt;/p&gt;

&lt;p&gt;At 60-66 primitive double is boxed into Double only to be converted back into primitive.&lt;/p&gt;

&lt;p&gt;The equivalent Java code compiles to much simpler and faster bytecode:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;&lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt; testCase(&lt;span class=&quot;code-object&quot;&gt;long&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;double&lt;/span&gt;);
  Code:
   0:	lload_1
   1:	l2i
   2:	lookupswitch{ &lt;span class=&quot;code-comment&quot;&gt;//1
&lt;/span&gt;		0: 20;
		&lt;span class=&quot;code-keyword&quot;&gt;default&lt;/span&gt;: 22 }
   20:	dload_3
   21:	dreturn
   22:	dload	5
   24:	dreturn
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</description>
                <environment></environment>
            <key id="14354">CLJ-740</key>
            <summary>Unnecessary boxing of primitives in case form</summary>
                <type id="1" iconUrl="http://dev.clojure.org/jira/images/icons/bug.gif">Defect</type>
                                <priority id="3" iconUrl="http://dev.clojure.org/jira/images/icons/priority_major.gif">Major</priority>
                    <status id="1" iconUrl="http://dev.clojure.org/jira/images/icons/status_open.gif">Open</status>
                    <resolution id="-1">Unresolved</resolution>
                                <assignee username="-1">Unassigned</assignee>
                                <reporter username="kryshen">Mikhail Kryshen</reporter>
                        <labels>
                    </labels>
                <created>Thu, 17 Feb 2011 02:49:45 -0600</created>
                <updated>Tue, 1 Mar 2011 02:51:43 -0600</updated>
                                    <version>Release 1.3</version>
                                                        <due></due>
                    <votes>0</votes>
                        <watches>1</watches>
                        <comments>
                    <comment id="26250" author="ataggart" created="Mon, 28 Feb 2011 14:16:07 -0600"  >&lt;p&gt;Improved via patch on &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-426&quot; title=&quot;case should handle hash collision&quot;&gt;&lt;del&gt;CLJ-426&lt;/del&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;(defn test-case ^double [^long i ^double d1 ^double d2]
  (case (int i)
    0 d1
    d2))
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;now emits as&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt; 0  lload_1 [i]
 1  invokestatic clojure.lang.RT.intCast(long) : int [67]
 4  istore 7 [G__7903] // let-bound expression
 6  iload 7 [G__7903]
 8  tableswitch default: 32
      case 0: 28
28  dload_3 [d2]
29  goto 34
32  dload 5 [arg2]
34  dreturn
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or if the int cast of the expression is omitted:&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt; 0  lload_1 [i]
 1  lstore 7 [G__7903] // let-bound expression
 3  lload 7 [G__7903]
 5  l2i
 6  tableswitch default: 35
      case 0: 24
24  lconst_0           // match, verify long expr wasn&apos;t truncated
25  lload 7 [G__7903]
27  lcmp
28  ifne 35
31  dload_3 [d2]
32  goto 37
35  dload 5 [arg2]
37  dreturn
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</comment>
                </comments>
                    <attachments>
                </attachments>
            <subtasks>
        </subtasks>
                <customfields>
                                                                                            <customfield id="customfield_10010" key="com.pyxis.greenhopper.jira:gh-global-rank">
                <customfieldname>Global Rank</customfieldname>
                <customfieldvalues>
                    
                </customfieldvalues>
            </customfield>
                                                                                                            </customfields>
    </item>
</channel>
</rss>