我想在Scala应用程序中对几种方法的运行时进行基准测试,我正在研究使用ScalaMeter。假设我想测量一个名为doSomething()
的方法的时间。
我只想调用doSomething
并测量运行一次所需的时间。但是,我在ScalaMeter中看到的所有文档都需要提供某种输入,无论是一系列整数,字符串还是其他东西。
是否可以使用ScalaMeter来完成我的要求?这是一个合适的用例吗?
答案 0 :(得分:1)
这是可能的,但这会浪费时间。
您可能已经意识到, ScalaMeter 旨在消除功能执行时间变化的影响,以便可以准确地对这些执行时间进行基准测试。例如,您可能希望验证函数是否在所需时间内完成,或者确定在对代码库进行更改时是否保持其性能。
为什么这么具有挑战性?那么,需要克服许多障碍:
size
上的List
操作 - 随着List
中元素数量的增加,执行时间显然会更长。)显然,基准测试应该在同一台主机上执行,以便结果具有可比性,因为CPU,操作系统,内存,BIOS配置等都会影响性能。
因此,在解释了所有这些之后,您将理解为什么 ScalaMeter 需要执行相同的函数很多!; - )
在您的情况下,doSomething()
不带参数,因此您可以使用Gen[T].single
生成器来标识doSomething()
所属的类或对象,其类似于以下内容:
注意:这是作为 ScalaMeter 测试编写的,因此源代码应位于src/test/scala
下:
import org.scalameter.api._
import org.scalameter.picklers.Implicits._
object MyBenchmark
extends Bench.ForkedTime {
// We have no arguments. Instead, create a single "generator" that identifies the class or
// object that doSomething belongs to. This assumes doSomething() belongs to object
// MyObject.
val owner = Gen.single("owner")(MyObject)
// Measure MyObject.doSomething()'s performance.
performance of "MyObject" in {
measure method "doSomething()" in {
using(owner) in {
_.doSomething()
}
}
}
}
(顺便说一句:我原本认为没有参数的基准测试功能会比这更简单,但这是迄今为止我能够提出的最佳功能。如果有人有更好的想法,请添加一个评论并告诉我!)
所以,如果所有这些都是矫枉过正的话,你可能想尝试这样的事情:
// Measure nanoseconds taken to execute by name argument.
def measureTime(x: => Unit): Long = {
val start = System.nanoTime()
x
// Calculate how long that took and return the value.
System.nanoTime() - start
}
measureTime {
doSomething()
}
你只会执行一次这个功能,每次花费的时间会大不相同。