문제

에서 허용된 최고의 응답 이 질문,거기에 명확한 설명을 왜 복싱 발생합니다.

그러나,면 디컴파일 코드(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();
      ()
    }
  }
}
.

왜 바이트 코드에서 권투의 증거가 보이지 않는 이유가 될 수 있습니다 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top