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

2024-03-12

我理解,根据以下问题,这些方法可能被视为“等效”或“同义词”,尽管不是“相同”是调用 collection.size 或 collection.length 的最佳 Scala 约定 https://stackoverflow.com/q/19671609/1296806 and Scala 缓冲区:大小还是长度? https://stackoverflow.com/q/14733833/1296806.

但这是否意味着它们是相同的?

不要向我提供意见或空洞的千篇一律的想法。只要告诉我它们实际上并不相同。

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

字节码就足够了。我对 JIT 特定的优化不太感兴趣。

我对世界的现状特别感兴趣,即 Scala 2.11 的最近里程碑。


在 2.11 中,字符串和数组的大小仍然是包装的。

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

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

从 Java 转向 Scala 的人经常会决定是否使用上面的方法java.lang.String或方便的增强。因为在我们被要求之前我们有一个有限的“决策预算”用甜甜圈补充它 http://seriouspony.com/blog/2013/7/24/your-app-makes-me-fat在休息室里,作为政策问题,值得提前做出一些决定。

如果大家在午餐或吃甜甜圈时没有更好的话题可以讨论:

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

等等,等等,使用 -optimise 你可能会丢失augmentString。

It's GenSeqLike介绍了length并指定它“产生相同的结果”size. SeqLike就是这样实现的。

实际上,String获得一个size方法通过增广到SeqLike, 具体来说,StringLike。这就需要包裹起来。事实上,预测哪些调用需要包装或分派到扩展方法并不容易。

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

但是,那apply方法上StringOps,定义为调用charAt模仿数组 apply,尽管以相同的方式定义,但调用扩展方法。

(当然,一些操作码和分配在 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;

length:

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

new StringOps, or 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       

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      

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      

and 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   
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 集合中的大小和长度生成相同的字节码吗? 的相关文章

随机推荐