Scala集合中的大小和长度是否生成相同的字节代码?

som*_*ytt 6 scala

我理解这些方法可能被认为是"等同的"或"同义词",尽管不是"相同的",根据诸如调用collection.size或collection.lengthScala Buffer 的最佳Scala约定之类的问题:大小或长度?.

但这是否意味着他们是一样的?

不要向我提供相同的意见或虚假的概念.告诉我他们什么时候不一样.

用坚硬的科学来支持你的主张!

字节代码就足够了.我对JIT特定的优化并不那么感兴趣.

我对世界目前的状况特别感兴趣,即最近的里程碑中的Scala 2.11.

som*_*ytt 8

字符串和数组仍然包装在2.11中.

你应该训练你的手指打字s.lengtharr.length.

这并不难,因为字符串和数组都有长度.

从Java进入Scala的人经常会决定是使用方法java.lang.String还是方便的扩充.由于在我们需要休息室的甜甜圈补充它之前我们有一个有限的"决策预算" ,因此作为一个政策问题,值得做出一些这些决定.

万一没有什么比午餐或甜甜圈更好的讨论了:

22: invokevirtual #41                 // Method scala/Predef$.augmentString:(Ljava/lang/String;)Ljava/lang/String;
25: invokespecial #44                 // Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
28: invokevirtual #47                 // Method scala/collection/immutable/StringOps.size:()I


18: invokevirtual #39                 // Method scala/Predef$.intArrayOps:([I)Lscala/collection/mutable/ArrayOps;
21: invokeinterface #44,  1           // InterfaceMethod scala/collection/mutable/ArrayOps.size:()I
Run Code Online (Sandbox Code Playgroud)

等等,等待,你可以失去augmentString.

GenSeqLike引入length并指定它"产生与...相同的结果" size. SeqLike以这种方式实现它.

实际上,通过增强来String获取一种size方法SeqLike,具体而言StringLike.这需要包装.实际上,要预测哪些调用需要换行或调度到扩展方法并不容易.

例如,length以不需要包装的方式定义.那是因为StringOps是一个价值类.事实上,它编译成String.length.

但是,apply方法on StringOps,定义为charAt模拟数组的调用,虽然以相同的方式定义,但调用扩展方法.

(当然,在JIT编译之后,一些操作码和分配可能没什么意义.)

scala> val s = "hello"
s: String = hello

scala> val n = s.length ; val i = s.size ; val c = s(4) ; s.slice(0,4)
n: Int = 5
i: Int = 5
c: Char = o
res0: String = hell

scala> :javap -prv -
  public $line4.$read$$iw$$iw$();
    flags: ACC_PUBLIC
    Code:
      stack=5, locals=7, args_size=1
         0: aload_0       
         1: invokespecial #32                 // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: putstatic     #34                 // Field MODULE$:L$line4/$read$$iw$$iw$;
         8: aload_0       
         9: getstatic     #39                 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
        12: invokevirtual #42                 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
Run Code Online (Sandbox Code Playgroud)

length:

        15: invokevirtual #47                 // Method java/lang/String.length:()I
        18: putfield      #22                 // Field n:I
        21: aload_0     
Run Code Online (Sandbox Code Playgroud)

new StringOps,或StringOops:

        22: new           #49                 // class scala/collection/immutable/StringOps
        25: dup           
        26: getstatic     #54                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
        29: getstatic     #39                 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
        32: invokevirtual #42                 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
        35: astore_2      
        36: astore_1      
        37: aload_2       
Run Code Online (Sandbox Code Playgroud)

StringOps.size:

        38: invokespecial #57                 // Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
        41: invokevirtual #60                 // Method scala/collection/immutable/StringOps.size:()I
        44: putfield      #25                 // Field i:I
        47: aload_0       
        48: getstatic     #65                 // Field scala/collection/immutable/StringOps$.MODULE$:Lscala/collection/immutable/StringOps$;
        51: getstatic     #54                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
        54: getstatic     #39                 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
        57: invokevirtual #42                 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
        60: astore        4
        62: astore_3      
        63: aload         4
        65: iconst_4      
Run Code Online (Sandbox Code Playgroud)

apply 扩展方法:

        66: invokevirtual #69                 // Method scala/collection/immutable/StringOps$.apply$extension:(Ljava/lang/String;I)C
        69: putfield      #28                 // Field c:C
        72: aload_0       
        73: getstatic     #65                 // Field scala/collection/immutable/StringOps$.MODULE$:Lscala/collection/immutable/StringOps$;
        76: getstatic     #54                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
        79: getstatic     #39                 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
        82: invokevirtual #42                 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
        85: astore        6
        87: astore        5
        89: aload         6
        91: iconst_0      
        92: iconst_4      
Run Code Online (Sandbox Code Playgroud)

并且slice:

        93: invokevirtual #73                 // Method scala/collection/immutable/StringOps$.slice$extension:(Ljava/lang/String;II)Ljava/lang/String;
        96: putfield      #31                 // Field res0:Ljava/lang/String;
        99: return   
Run Code Online (Sandbox Code Playgroud)