我正在比较两个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.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。