目前 Clojure 编译器总是将值发出到 set!
表达式时装箱,并在必要时解箱。可以将 AssignExpr 至 MaybePrimitiveExpr 以避免不必要的装箱/解箱。
假设此代码
`
public class Test {
public int x;
}
`
`
(defn foo []
(let [a (int 1)]
(set! (.-x (Test.)) a)
"asd"))
`
原始
`
public static java.lang.Object invokeStatic();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=1, args_size=0
0: lconst_1
1: invokestatic #17 // Method clojure/lang/RT.intCast:(J)I
4: istore_0
5: new #19 // class Test
8: dup
9: invokespecial #20 // Method Test."<init>":()V
12: checkcast #19 // class Test
15: iload_0
16: invokestatic #26 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
19: dup_x1
20: checkcast #28 // class java/lang/Number
23: invokestatic #31 // Method clojure/lang/RT.intCast:(Ljava/lang/Object;)I
26: putfield #35 // Field Test.x:I
29: pop
30: ldc #37 // String asd
32: areturn
LocalVariableTable:
Start Length Slot Name Signature
5 27 0 a I
LineNumberTable:
line 3: 0
line 4: 1
line 5: 19
`
修改后
`
public static java.lang.Object invokeStatic();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=1, args_size=0
0: lconst_1
1: invokestatic #17 // Method clojure/lang/RT.intCast:(J)I
4: istore_0
5: new #19 // class Test
8: dup
9: invokespecial #20 // Method Test."<init>":()V
12: checkcast #19 // class Test
15: iload_0
16: dup_x1
17: putfield #24 // Field Test.x:I
20: pop
21: ldc #26 // String asd
23: areturn
LocalVariableTable:
Start Length Slot Name Signature
5 18 0 a I
LineNumberTable:
line 3: 0
line 4: 1
line 5: 16
`
补丁: 0001-CLJ-2282-don-t-unnecessarily-box-primitive-set-val.patch