Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 慢速Scala断言_Performance_Scala_Profiling_Assert_Preconditions - Fatal编程技术网

Performance 慢速Scala断言

Performance 慢速Scala断言,performance,scala,profiling,assert,preconditions,Performance,Scala,Profiling,Assert,Preconditions,我们最近一直在分析我们的代码,我们遇到了一些恼人的热点。它们在表格中 assert(a == b, a + " is not equal to " + b) 因为这些断言中的一些可以在代码中被调用,字符串concat开始累积的次数非常多断言定义为: def assert(assumption : Boolean, message : Any) = .... def assert(assumption : Boolean, message : => Any) = .... 为什么不将其

我们最近一直在分析我们的代码,我们遇到了一些恼人的热点。它们在表格中

assert(a == b, a + " is not equal to " + b)
因为这些断言中的一些可以在代码中被调用,字符串concat开始累积的次数非常多<代码>断言定义为:

def assert(assumption : Boolean, message : Any) = ....
def assert(assumption : Boolean, message : => Any) = ....
为什么不将其定义为:

def assert(assumption : Boolean, message : Any) = ....
def assert(assumption : Boolean, message : => Any) = ....
那样的话,它会懒散地评估。既然没有这样定义,那么有没有一种内联方式来调用带有延迟计算的消息参数的assert


感谢

惰性求值对创建的函数对象也有一些开销。如果您的消息对象已完全构造(静态消息),则此开销是不必要的

适合您的用例的方法是sprintf风格:

assert(a == b,  "%s is not equal to %s", a, b)
只要有一个特殊化的函数

assert(Boolean, String, Any, Any)
此实现没有var args数组的开销或成本

assert(Boolean, String, Any*)
对于一般情况

实现toString将被延迟评估,但不可读:

assert(a == b, new { override def toString =  a + " is not equal to " + b })
尝试:
assert(a==b,“%s不等于%s”。格式(a,b))

仅当断言需要字符串时才应调用该格式。格式通过隐式添加到RichString中。

托马斯的答案很好,但如果你喜欢最后一个答案的想法,但不喜欢不可读性,你可以绕过它:

object LazyS {
  def apply(f: => String): AnyRef = new {
    override def toString = f
  }
}
例如:

object KnightSpeak {
  override def toString = { println("Turned into a string") ; "Ni" }
}

scala> assert(true != false , LazyS("I say " + KnightSpeak))

scala> println( LazyS("I say " + KnightSpeak) )
Turned into a string
I say Ni

这是名字,我一年多前改的

当前Predef:

@elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
  if (!assertion)
    throw new java.lang.AssertionError("assertion failed: "+ message)
}

这是错误的,原因正是提问者强调的:assert方法采用了
Any
,而不是
=>Any
,我很确定格式中没有魔法,所以无论a==b是否为真,它都会被正常调用。哦。我是id10t。很明显,谢谢你,托马斯。我没有考虑懒惰评估的开销。从我们的代码来看,延迟求值的开销比字符串concat低得多,因此我认为我们将继续编写自己的assert方法。它不漂亮,但速度快了很多。@extempore:这是2.8版的吗?还是2.7呢?对于那些不知道的人来说,这是在2.8中修正的。