- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
AnyRef specialization is too timid?
Given
class Spec[@specialized(Int, AnyRef) A, @specialized(Long) B](val a: A, val b: B) { }
object Tested {
val x = new Spec(5, 5L)
val y = new Spec("Fish", 5L)
val z = new Spec(true, 5L)
}
one might hope that the Long would be specialized in every case. This is entirely reasonable to expect, given that "true" gets packaged into an AnyRef via java.lang.Boolean. Unfortunately, we see:
public Tested$();
Code:
0: aload_0
1: invokespecial #32; //Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #34; //Field MODULE$:LTested$;
8: aload_0
9: new #36; //class Spec$mcIJ$sp
12: dup
13: iconst_5
14: ldc2_w #37; //long 5l
17: invokespecial #41; //Method Spec$mcIJ$sp."<init>":(IJ)V
20: putfield #23; //Field x:LSpec;
23: aload_0
24: new #43; //class Spec$mcTJ$sp
27: dup
28: ldc #45; //String Fish
30: ldc2_w #37; //long 5l
33: invokespecial #48; //Method Spec$mcTJ$sp."<init>":(Ljava/lang/Object;J)V
36: putfield #26; //Field y:LSpec;
39: aload_0
40: new #50; //class Spec
43: dup
44: iconst_1
45: invokestatic #56; //Method scala/runtime/BoxesRunTime.boxToBoolean:(Z)Ljava/lang/Boolean;
48: ldc2_w #37; //long 5l
51: invokestatic #60; //Method scala/runtime/BoxesRunTime.boxToLong:(J)Ljava/lang/Long;
54: invokespecial #63; //Method Spec."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
57: putfield #29; //Field z:LSpec;
60: return
meaning that we've boxed the Long as well (#51).
I have been unable to anticipate any case where this is the most desirable behavior.
Am I missing something?
This is causing me considerable frustration as I try to specialize a library, since if the user asks for a single type that I omit, everything defaults to the slowest possible case. So the user (e.g. me) has to remember exactly what is specialized and what is not, and wrap the non-specialized ones by hand in order to gain the benefit of the arguments that are specialized.
--Rex
class Spec[@specialized(Int, AnyRef) A, @specialized(Long) B](val a: A, val b: B) { }
object Tested {
val x = new Spec(5, 5L)
val y = new Spec("Fish", 5L)
val z = new Spec(true, 5L)
}
one might hope that the Long would be specialized in every case. This is entirely reasonable to expect, given that "true" gets packaged into an AnyRef via java.lang.Boolean. Unfortunately, we see:
public Tested$();
Code:
0: aload_0
1: invokespecial #32; //Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #34; //Field MODULE$:LTested$;
8: aload_0
9: new #36; //class Spec$mcIJ$sp
12: dup
13: iconst_5
14: ldc2_w #37; //long 5l
17: invokespecial #41; //Method Spec$mcIJ$sp."<init>":(IJ)V
20: putfield #23; //Field x:LSpec;
23: aload_0
24: new #43; //class Spec$mcTJ$sp
27: dup
28: ldc #45; //String Fish
30: ldc2_w #37; //long 5l
33: invokespecial #48; //Method Spec$mcTJ$sp."<init>":(Ljava/lang/Object;J)V
36: putfield #26; //Field y:LSpec;
39: aload_0
40: new #50; //class Spec
43: dup
44: iconst_1
45: invokestatic #56; //Method scala/runtime/BoxesRunTime.boxToBoolean:(Z)Ljava/lang/Boolean;
48: ldc2_w #37; //long 5l
51: invokestatic #60; //Method scala/runtime/BoxesRunTime.boxToLong:(J)Ljava/lang/Long;
54: invokespecial #63; //Method Spec."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
57: putfield #29; //Field z:LSpec;
60: return
meaning that we've boxed the Long as well (#51).
I have been unable to anticipate any case where this is the most desirable behavior.
Am I missing something?
This is causing me considerable frustration as I try to specialize a library, since if the user asks for a single type that I omit, everything defaults to the slowest possible case. So the user (e.g. me) has to remember exactly what is specialized and what is not, and wrap the non-specialized ones by hand in order to gain the benefit of the arguments that are specialized.
--Rex









