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

数组 – 为什么Array.slice如此(令人震惊!)慢?

发布时间:2020-12-16 09:43:37 所属栏目:安全 来源:网络整理
导读:这是我的基准代码: def bm(duration: Long)(f: = Unit)={ val end = System.currentTimeMillis + duration var count = 0 while(System.currentTimeMillis end) { f; count += 1 } count}val array = new scala.util.Random().alphanumeric.take(1000).toAr
这是我的基准代码:

def bm(duration: Long)(f: => Unit)={
  val end = System.currentTimeMillis + duration
  var count = 0
  while(System.currentTimeMillis < end) { f; count += 1 }
  count
}

val array = new scala.util.Random().alphanumeric.take(1000).toArray

(1 to 20).map { _ => bm(1000) { array.slice(100,200) } }.sum / 20

运行这几次,我一直得到每秒大约150万片的球场数量。 1.4和1.6之间。

现在,我这样做:

implicit class FastSlicing(val a: Array[Char]) extends AnyVal {
   def fastSlice(from: Int,until: Int)  = Arrays.copyOfRange(a,from,until)
 }
 (1 to 20).map { _ => bm(1000) { array.fastSlice(100,200) } }.sum / 20

我得到的结果是每秒16到1800万片。
这是快10倍以上。

现在,我知道所有关于scala为提供功能性成语和类型安全的权衡的常见推理,有时以牺牲性能为代价…
但在这种情况下,我认为他们都没有回答一个简单的问题:为什么ArrayOps.slice不这样实现?我意识到,将需要多个相同的实现,因为java处理原始数组的方式,但这至少是一个小小的麻烦,而不是真正的交易破坏者的一个问题来证明10倍的性能命中。

.slice只是一个例子,大多数其他数组操作似乎也遭受同样的问题。为什么要这样呢?

现在更新,这里是我觉得更令人震惊的事情:

val seq = new scala.util.Random().alphanumeric.take(1000).toIndexedSeq
(1 to 20).map { _ => bm(1000) { seq.slice(100,200) } }.sum / 20

这对我来说每秒大约有5-6万片。但是这个:

import scala.collections.JavaConversions._
(1 to 20).map { _ => bm(1000) { seq.subList(100,200) } }.sum / 20

确实在12到1500万!
这样做并不是数组的大小差异,就像在数组的情况下一样,但是(1)这里没有特别处理这些原语,所以使用java标准工具实现这一点是非常简单的,(2)收集是不可变的…返回一个引用范围的索引有多难?

解决方法

已在 scala 2.12修复。

(编辑:李大同)

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

    推荐文章
      热点阅读