- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我感觉 Scala 社区对写“简洁”、“酷”的东西有点痴迷, "scala 惯用语" , "one-liner"- 如果可能的话 - 代码。紧接着是与 Java/命令式/丑陋代码的比较。
虽然这(有时)会导致代码易于理解,但它也会导致 99% 的开发人员代码效率低下。这就是 Java/C++ 不容易被击败的地方。
考虑这个简单的问题:给定一个整数列表,删除最大的元素。 排序不需要保留。
这是我的解决方案版本(它可能不是最好的,但这是普通的非摇滚明星开发人员会做的)。
def removeMaxCool(xs: List[Int]) = {
val maxIndex = xs.indexOf(xs.max);
xs.take(maxIndex) ::: xs.drop(maxIndex+1)
}
def removeMaxFast(xs: List[Int]) = {
var res = ArrayBuffer[Int]()
var max = xs.head
var first = true;
for (x <- xs) {
if (first) {
first = false;
} else {
if (x > max) {
res.append(max)
max = x
} else {
res.append(x)
}
}
}
res.toList
}
最佳答案
让我们讨论一下问题中的一个谬误:
So, if 99% of Java developers write more efficient code than 99% of Scala developers, this is a huge obstacle to cross for greater Scala adoption. Is there a way out of this trap?
Totally non-Scala idiomatic, non-functional, non-concise, but it's very efficient. It traverses the list only once!
res.append(max)
res.append(x)
res.toList
append
.
append
采用可变参数。这意味着 max
和 x
首先封装成某种类型的序列(实际上是 WrappedArray
),然后作为参数传递。更好的方法是 +=
. append
电话++=
, 委托(delegate)给 +=
.但是,首先,它调用 ensureSize
,这是第二个错误( +=
也调用了它——++=
只是针对多个元素优化了它)。因为一个 Array
是一个固定大小的集合,这意味着在每次调整大小时,整个 Array
必须复制! ArrayBuffer
来改进这一点。初始大小等于将要读取的列表减去一,因为我们将丢弃一个元素。不过,为了获得这个大小,我们需要遍历列表一次。
toList
.简单来说,就是遍历整个链表来创建一个新链表。
toList
的 1 次额外遍历。 .那是 4 或 5 次遍历。
take
,
drop
和
:::
遍历可变数量的元素。然而,将所有这些加在一起,它相当于 3 次遍历。如
splitAt
被使用,它将减少到 2 次遍历。再进行 2 次遍历以获得最大值,我们得到 5 次遍历——与非功能性、非简洁算法相同的数量!
ListBuffer
和
+=
,那么所有方法都是恒定时间的,这将其减少为一次遍历。
val max = xs.max
val (before, _ :: after) = xs span (max !=)
before ::: after
O(n)
,而唯一一个几乎(意外地)导致最坏复杂性的是命令式的(因为数组复制)。另一方面,命令式的缓存特性可能会使其更快,因为数据在内存中是连续的。然而,这与 big-Oh 或函数式 vs 命令式无关,这只是选择的数据结构的问题。
Vector
取而代之,左右两边基本保持不变,这可能会带来更好的性能。 关于scala - Scala 惯用的编码风格只是编写低效代码的一个很酷的陷阱吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7084212/
我写了一个函数,应该用值替换两个定界符之间的代码,它返回(我将其应用到的字符串是 HTML 对象的 .outerHTML)。 这将类似于它在例如中的使用方式。 Vue.js 或 Angular。 看起
好的,我有一个 Django View ,如下所示: @render_to('home/main.html') def login(request): # also tried Client.
由于我创建的几乎所有项目都包含 ListView,因此我想到创建一个类,其中包含修改 ListView 的所有重要功能。它看起来像这样: 主窗体: ListViewFunctions LVF = ne
The default implementation on Stream creates a new single-byte array and then calls Read. While this
我当然不是 Drupal 专家,但我之前设计并构建了一些数据库,所以我对第 3 方团队正在处理的数据库结构感到困惑,我已经将 Sequel Pro 添加到其中虚拟内容。我认为如果使用 Drupal 的
我想生成一个随机的短十六进制字符串(比如 8 位或 16 位)。 有很多选择可以做到这一点,例如,从我的头顶开始: uuid.uuid4().hex[:8] md5().hexdigest()[:8]
我是一名优秀的程序员,十分优秀!