慢斯卡拉断言

Posted

技术标签:

【中文标题】慢斯卡拉断言【英文标题】:Slow Scala assert 【发布时间】:2010-03-11 13:10:43 【问题描述】:

我们最近一直在分析我们的代码,并且遇到了一些烦人的热点。它们的形式是

assert(a == b, a + " is not equal to " + b)

因为其中一些断言可以在代码中多次调用,因此字符串 concat 开始累加。 assert 定义为:

def assert(assumption : Boolean, message : Any) = ....

为什么不定义为:

def assert(assumption : Boolean, message : => Any) = ....

这样它会懒惰地评估。鉴于它没有以这种方式定义,是否有一种内联方式来调用带有延迟评估的消息参数的断言?

谢谢

【问题讨论】:

对于那些不知道的人,这已在 2.8 中修复。 【参考方案1】:

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

适合您的用例的方法是 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 )

【讨论】:

谢谢托马斯。我没有考虑惰性评估的开销。从我们的代码来看,惰性求值的开销远低于字符串 concat,所以我认为我们将继续编写自己的断言方法。这不是很漂亮,但速度很快。【参考方案2】:

它是别名,一年多前我改了。

http://www.scala-lang.org/node/825

当前预定义:

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

【讨论】:

@extempore:仅适用于 2.8 吗?还是 2.7?【参考方案3】:

Thomas 的答案很棒,但如果您喜欢最后一个答案的想法但不喜欢不可读性,您可以绕过它:

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

【讨论】:

【参考方案4】:

试试:assert( a==b, "%s is not equals to %s".format(a,b)) 仅当断言需要字符串时才应调用格式。格式通过隐式添加到 RichString 中。

【讨论】:

这是错误,正是因为提问者强调的原因:断言方法采用Any 而不是=> Any 我很确定格式没有什么神奇之处,所以无论 a==b 是否为真,它都会被正常调用。 哦。我是一个id10t。现在很明显了。

以上是关于慢斯卡拉断言的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter(二十一) - 从入门到精通 - JMeter断言 - 上篇(详解教程)

看完我这篇文字所有断言讲解,Jmeter性能,压测,接口,这些都是小题。

JMeter断言之JSON断言

jmter添加断言

正则断言详解

Jmeter之断言(3种)