如何在scala控制台中测量语句的时间?

Pio*_*pla 30 regex scala

我正在使用Scala来衡量java的正则表达式引擎的性能.下面的正则表达式大约在3秒内执行,但我无法使用System.currentTimeMillis进行测量.(最后一个表达式返回0)

scala> val b = System.currentTimeMillis; val v = new Regex("(x+)+y").findAllIn("x"*25); b-System.currentTimeMillis
b: Long = 1330787275629
v: scala.util.matching.Regex.MatchIterator = empty iterator
res18: Long = 0
Run Code Online (Sandbox Code Playgroud)

您现在为什么最后返回的值为0,而不是scala在执行regexp时花费的ms量?

ret*_*nym 81

原因不明的持续时间来自REPL调用toString返回的迭代器findAllIn.这反过来调用Regex.MatchIterator#hasNext,触发搜索.

scala> def time[A](a: => A) = {
     |   val now = System.nanoTime
     |   val result = a
     |   val micros = (System.nanoTime - now) / 1000
     |   println("%d microseconds".format(micros))
     |   result
     | }
time: [A](a: => A)A

scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'.          **
** scala.tools.nsc._ has been imported      **
** global._, definitions._ also imported    **
** Try  :help, :vals, power.<tab>           **

scala> :wrap time
Set wrapper to 'time'

scala> new Regex("(x+)+y").findAllIn("x"*25).toString
3000737 microseconds
res19: String = empty iterator

scala> {new Regex("(x+)+y").findAllIn("x"*25); 0}
582 microseconds
res20: Int = 0
Run Code Online (Sandbox Code Playgroud)

  • 对于`:wrap`示例+1,虽然我不确定简单的减法是在JVM中对小块代码进行基准测试的最佳方法 (7认同)
  • 在REPL中不再出现`:wrap`?在Windows的Scala 2.10.2中,我得到`wrap:no such命令.输入:求助帮助 (5认同)
  • 是的,`:wrap`已删除:https://groups.google.com/d/msg/scala-user/cE-z6fxkq0U/EszYr_19qgMJ (3认同)
  • 你是对的,谷歌的Caliper是一个更全面的工具,它已经很好地包含在基于SBT的基准测试平台中:https://github.com/sirthias/scala-benchmarking-template/network (2认同)

kir*_*uku 28

def time[A](f: => A) = {
  val s = System.nanoTime
  val ret = f
  println("time: "+(System.nanoTime-s)/1e6+"ms")
  ret
}
Run Code Online (Sandbox Code Playgroud)

使用它:

scala> time { 10*2 }
time: 0.054212ms
res1: Int = 20
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是测试时间的一种更简洁的方式,但它并没有回答这个具体问题,因为问题实际上是由被评估的代码实际上没有做OP正在尝试测量的内容引起的. (4认同)

Rus*_*ell 5

这很有意思!我添加了一个println("start")"end"周围创建正则表达式并运行代码行-这版画

start 
end
Run Code Online (Sandbox Code Playgroud)

然后在打印输出的其余部分之前暂停约三秒钟.

所以看起来正在发生的是正在创建的正则表达式,但是直到toString被调用才能将其输出到控制台.要使测试起作用,toString请在计算花费的时间之前添加手动调用.

scala> val b = System.currentTimeMillis; val v = new scala.util.matching.Regex("(x+)+y").findAllIn("x"*25); v.toString; System.currentTimeMillis-b
b: Long = 1330789547209
v: scala.util.matching.Regex.MatchIterator = empty iterator
res14: Long = 4881
Run Code Online (Sandbox Code Playgroud)

它应该是System.currentTimeMillis-b而不是相反...