加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么Scala的foldLeft具有比使用字符串索引迭代更低的性能?

发布时间:2020-12-16 19:06:09 所属栏目:安全 来源:网络整理
导读:我正在比较两个atoi实现的性能.第一个是使用charAt迭代输入字符串获取chars;第二个是使用foldLeft. object Atoi { def withRandomAccess(str: String,baze: Int): Int = { def process(acc: Int,place: Int,str: String,index: Int): Int = if (index = 0) p
我正在比较两个atoi实现的性能.第一个是使用charAt迭代输入字符串获取chars;第二个是使用foldLeft.

object Atoi {
  def withRandomAccess(str: String,baze: Int): Int = {
      def process(acc: Int,place: Int,str: String,index: Int): Int = 
        if (index >= 0) process(acc + value(str.charAt(index)) * place,place * baze,str,index-1) else acc
      process(0,1,str.length - 1)
    }

  def withFoldLeft(str: String,base: Int): Int = (0/:str) (_ * base + value(_))

  def value(c: Char): Int = { /* omitted for clarity */ }

  def symbol(i: Int): Char = { /* omitted for clarity */ }
}

foldLeft版本的速度是2x到4x(完整的基准代码是here).我没想到这个你知道为什么吗?在处理它之前,Scala是否将字符串转换为列表?你有什么提示如何提高foldLeft性能的字符串?

解决方法

这个问题与内联无关,它与使用foldLeft时所发生的Chars的拳击/拆箱有关.

您可以通过隐式转换为StringOps的String获取foldLeft,这不是专门的. String中的每个char必须被包装成一个java.lang.Character,以便被传递给Function2(foldLeft的参数),然后取消装箱(便宜得多)传递给函数体内的值方法,然后装箱再次进入折叠的下一个迭代.

拳击涉及创建对象和随后垃圾回收的开销.

在避免拳击方面,有一个简短而重要的一点:

>你不应该试图避免拳击,几率接近1.

(也就是说,除非你已经确定了可以归结于拳击的具体和不可接受的性能下降,否则你不应该担心.)

如果您确定需要解决的问题,请避免收集和理解(在引导下使用foreach和flatMap).如果您正在使用循环,请使用while.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读