我正在将一些代码转换为Scala。它的代码位于具有大量数据的内部循环中,因此需要快速,并且它涉及在哈希表中查找键并计算概率。根据是否找到密钥,它需要做不同的事情。使用“标准”习语代码看起来像这样:
counts.get(word) match {
case None => {
WordDist.overall_word_probs.get(word) match {
case None => (unseen_mass*WordDist.globally_unseen_word_prob
/ WordDist.num_unseen_word_types)
case Some(owprob) => unseen_mass * owprob / overall_unseen_mass
}
}
case Some(wordcount) => wordcount.toDouble/total_tokens*(1.0 - unseen_mass)
}
但是我担心这种代码会非常慢,因为所有这些临时的Some()对象都被创建然后被垃圾收集。 Scala2e的书声称智能JVM“可能”优化它们,以便代码在效率方面做正确的事情,但这实际上是否使用Sun的JVM?有人知道吗?
答案 0 :(得分:2)
如果您在jvm中启用escape analysis,可能会发生这种情况,启用时为:
-XX:+DoEscapeAnalysis
在JRE 1.6上。从本质上讲,它应该检测正在创建的对象,这些对象不会从方法激活框架中转义,并且在不再需要它们之后立即将它们分配到堆栈或GC上。
您可以做的一件事是使用scala.testing.Benchmark
特征对代码进行微观基准测试。只需使用单个对象扩展它并实现run
方法,编译并运行它。它将多次运行run
方法,并测量执行时间。
答案 1 :(得分:1)
是的,将创建Some
个对象(None
是单个对象)。当然,JVM除外 - 这取决于很多因素,包括JVM是否认为代码被调用了很多。
无论如何,那段代码并不是真正的标准习语。甚至还有一个关于它的模因:曾经,一位经验丰富的Scala开发人员编写了这样的代码,当另一个人回答“这是什么?业余时间?平面图那个sh * t!”
无论如何,这是我如何重写它:
( counts
get word
map (_.toDouble / total_tokens * (1.0 - unseen_mass))
getOrElse (
WordDist.overall_word_probs
get word
map (unseen_mass * _ / overall_unseen_mass)
getOrElse (unseen_mass * WordDist.globally_unseen_word_prob
/ WordDist.num_unseen_word_types)
)
)
然后你可以重构这一点 - 两个getOrElse
参数都可以用不同的方法拆分。因为它们只返回没有输入的值,所以它们应该非常快。
现在,我们在Option
:map
和getOrElse
只调用两种方法。这是他们实施的开始:
@inline final def map
@inline final def getOrElse
由于getOrElse
的参数是按名称传递的,因此它涉及匿名函数创建。当然,map
的参数也是一个函数。除此之外,这些方法内联的可能性非常大。
所以,这是重构的代码,虽然我不太了解它的名字。
def knownWordsFrequency = counts get word map computeKnownFrequency
def computeKnownFrenquency =
(_: Int).toDouble / total_tokens * (1.0 - unseen_mass)
def probableWordsFrequency = (
WordDist.overall_word_probs
get word
map computeProbableFrequency
)
def computeProbableFrequency = unseen_mass * (_: Double) / overall_unseen_mass
def unknownFrequency = (unseen_mass * WordDist.globally_unseen_word_prob
/ WordDist.num_unseen_word_types)
def estimatedWordsFrequency = probablyWordsFrequency getOrElse unknownFrequency
knownWordsFrequency getOrElse estimatedWordsFrequency