을 인식하는 방법 복싱/unboxing 에 디컴파일된 밀라노 코드?
문제
에서 허용된 최고의 응답 이 질문,거기에 명확한 설명을 왜 복싱 발생합니다.
그러나,면 디컴파일 코드(java 를 사용하여 디컴파일러)나는 볼 수 없습의 사용입니다.런타임입니다.BoxesRunTime.또한,면 내 프로파일 코드를 사용하여(JProfiler)나는 볼 수 없습니다 모든 인스턴스의 BoxesRunTime.
그래서,어떻게 정말 보는 증거의 복싱/unboxing 어나고 있는가?
해결책
이 코드:
class Foo[T] {
def bar(i: T) = i
}
object Main {
def main(args: Array[String]) {
val f = new Foo[Int]
f.bar(5)
}
}
의 호출 bar
먼저자의 정수입니다.컴파일과 스칼라 2.8.1 및 사용:
javap -c -l -private -verbose -classpath <dir> Main$
보 바이트 코드의 생산에 대 한 main
방법 Main
클래 수익률:
public void main(java.lang.String[]);
...
9: iconst_5
10: invokestatic #24; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: invokevirtual #28; //Method Foo.bar:(Ljava/lang/Object;)Ljava/lang/Object;
16: pop
17: return
...
당신이 볼 수있는 전화 BoxesRunTime
전화 bar
.
BoxesRunTime
는 개체를 포함하는 복싱 방법에 대한 기본 형식이 있어야하므로 정확히 하나의 인스턴스입니다.트릭 여기에는 이 특정 라이브러리에서 파일에 기록되었 Java,변환은 정적인 방법입니다.이러한 이유로 없습니다 인스턴스에서 런타임 설정을 사용하지만 그것은 스칼라에 코드를 느끼는 것처럼 개체입니다.
당신은 아마 보일한 박스 프리미티브(예:java.랭.Integer)JProfile 지만,나는 불확실한 방법 JVM 작동하는지 여부와 수 있습니다 실제로 그것은 다시 쓰는 코드에서 런타임 최적화를 방지하기 위해 복싱습니다.내 지식,그것은 없 적용 특성화(하지만 믿 CLR 는 않습니다).몇 microbenchmarks 없이 복싱의 상황은 다른 방법을 파악하는 것에서 발생합니다.
편집:
위의 경우 입력 매개변수는 없으로 주석 @specialized
주석이 있습니다.이 경우에는 복싱/unboxing 피할 수 있습니다.특정 클래스에서는 표준 라이브러리는 전문했습니다.보 이 sid.
다른 팁
다음 test.scala 프로그램을 감안할 때 :
object Test {
def main(args:Array[String]) {
val list = List(1,5,15)
val res = list.map(e => e*2).filter(e => e>10)
}
}
.
scalac -Xprint:jvm Test.scala
로 컴파일하는 경우 전문화가 발생하는이 스 니펫을 제안합니다 (와이드 페이스트 죄송합니다) :
package <empty> {
final class Test extends java.lang.Object with ScalaObject {
def main(args: Array[java.lang.String]): Unit = {
val list: List = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 5, 15}));
val res: List = list.map({
(new Test$$anonfun$1(): Function1)
}, immutable.this.List.canBuildFrom()).$asInstanceOf[scala.collection.TraversableLike]().filter({
(new Test$$anonfun$2(): Function1)
}).$asInstanceOf[List]();
()
};
def this(): object Test = {
Test.super.this();
()
}
};
@SerialVersionUID(0) @serializable final <synthetic> class Test$$anonfun$1 extends scala.runtime.AbstractFunction1$mcII$sp {
final def apply(e: Int): Int = Test$$anonfun$1.this.apply$mcII$sp(e);
<specialized> def apply$mcII$sp(v1: Int): Int = v1.*(2);
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = scala.Int.box(Test$$anonfun$1.this.apply(scala.Int.unbox(v1)));
def this(): Test$$anonfun$1 = {
Test$$anonfun$1.super.this();
()
}
};
@SerialVersionUID(0) @serializable final <synthetic> class Test$$anonfun$2 extends scala.runtime.AbstractFunction1$mcZI$sp {
final def apply(e: Int): Boolean = Test$$anonfun$2.this.apply$mcZI$sp(e);
<specialized> def apply$mcZI$sp(v1: Int): Boolean = v1.>(10);
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = scala.Boolean.box(Test$$anonfun$2.this.apply(scala.Int.unbox(v1)));
def this(): Test$$anonfun$2 = {
Test$$anonfun$2.super.this();
()
}
}
}
.
왜 바이트 코드에서 권투의 증거가 보이지 않는 이유가 될 수 있습니다 ...