I am trying to do a pattern match on the boolean value. I have written the same method with a slight modification but there is much difference in their bytecode generation.
For example
scala> def compare(flag: Boolean) = {
| flag match{
| case true => println("true..")
| case false => println("false...")
| }}
compare: (flag: Boolean)Unit
scala> :javap -c compare
Compiled from "<console>"
public class $line4.$read$$iw$$iw$ {
public static $line4.$read$$iw$$iw$ MODULE$;
public static {};
Code:
0: new #2 // class $line4/$read$$iw$$iw$
3: invokespecial #17 // Method "<init>":()V
6: return
public void compare(boolean);
Code:
0: iload_1
1: istore_3
2: iconst_1
3: iload_3
4: if_icmpne 22
7: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
10: ldc #27 // String true..
12: invokevirtual #31 // Method scala/Predef$.println:(Ljava/lang/Object;)V
15: getstatic #37 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
18: astore_2
19: goto 60
22: goto 25
25: iconst_0
26: iload_3
27: if_icmpne 45
30: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
33: ldc #39 // String false...
35: invokevirtual #31 // Method scala/Predef$.println:(Ljava/lang/Object;)V
38: getstatic #37 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
41: astore_2
42: goto 60
45: goto 48
48: new #41 // class scala/MatchError
51: dup
52: iload_3
53: invokestatic #47 // Method scala/runtime/BoxesRunTime.boxToBoolean:(Z)Ljava/lang/Boolean;
56: invokespecial #49 // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
59: athrow
60: return
public $line4.$read$$iw$$iw$();
Code:
0: aload_0
1: invokespecial #52 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #54 // Field MODULE$:L$line4/$read$$iw$$iw$;
8: return
}
When I do the same thing using if expression, there is different bytecode.
scala> def compareAgain(flag: Boolean) = {
| if(flag) println("true..")
| else println("false...")
| }
compareAgain: (flag: Boolean)Unit
scala> :javap -c compareAgain
Compiled from "<console>"
public class $line5.$read$$iw$$iw$ {
public static $line5.$read$$iw$$iw$ MODULE$;
public static {};
Code:
0: new #2 // class $line5/$read$$iw$$iw$
3: invokespecial #17 // Method "<init>":()V
6: return
public void compareAgain(boolean);
Code:
0: iload_1
1: ifeq 15
4: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
7: ldc #27 // String true..
9: invokevirtual #31 // Method scala/Predef$.println:(Ljava/lang/Object;)V
12: goto 23
15: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
18: ldc #33 // String false...
20: invokevirtual #31 // Method scala/Predef$.println:(Ljava/lang/Object;)V
23: return
public $line5.$read$$iw$$iw$();
Code:
0: aload_0
1: invokespecial #36 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #38 // Field MODULE$:L$line5/$read$$iw$$iw$;
8: return
}
There is different bytecode. What does this mean in first bytecode?
// Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
Thanks in advance.
This is a duplicate of this question that was answered for the old pattern matcher and the old backend. Notice how life was simpler back then.
For the new and improved, you can get the code you want with an optimizer option. I don't know why they make you jump through hoops.
$ scala -opt:copy-propagation
Welcome to Scala 2.12.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.
scala> def f(b: Boolean) = b match { case true => println() ; case _ => println() }
f: (b: Boolean)Unit
scala> :javap -c f
Compiled from "<console>"
public class $line3.$read$$iw$$iw$ {
public static $line3.$read$$iw$$iw$ MODULE$;
public static {};
Code:
0: new #2 // class $line3/$read$$iw$$iw$
3: invokespecial #17 // Method "<init>":()V
6: return
public void f(boolean);
Code:
0: iconst_1
1: iload_1
2: if_icmpne 14
5: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
8: invokevirtual #28 // Method scala/Predef$.println:()V
11: goto 26
14: goto 17
17: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
20: invokevirtual #28 // Method scala/Predef$.println:()V
23: goto 26
26: return
public $line3.$read$$iw$$iw$();
Code:
0: aload_0
1: invokespecial #31 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #33 // Field MODULE$:L$line3/$read$$iw$$iw$;
8: return
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With