慢斯卡拉断言
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断言 - 上篇(详解教程)