我可以在没有输入的情况下使用ScalaMeter吗?

干草

我想在我的Scala应用程序中对几种方法的运行时间进行基准测试,并且正在考虑使用ScalaMeter。假设我要测量称为的方法的时间doSomething()

我只想调用doSomething并测量一次运行所需的时间。但是,我为ScalaMeter看到的所有文档都需要提供某种输入,无论它是一系列整数,字符串还是其他东西。

是否可以使用ScalaMeter来完成我要求的操作?这是一个合适的用例吗?

迈克·艾伦

可以,但是会浪费时间。

您可能已经知道,ScalaMeter旨在消除函数执行时间变化的影响,因此可以准确地确定那些执行时间的基准。例如,您可能想验证功能是否在要求的时间内完成,或者确定随着对代码库的更改,该功能的性能是否随着时间的推移得以保持。

为什么这么有挑战性?好吧,有许多障碍需要克服:

  1. JVM有许多用于执行所产生的不同选择Java字节码的程序。有些(例如Zero VM)只是解释代码;有些则只是解释代码。其他人则利用即时JIT)编译来优化对主机CPU的机器代码的转换热点服务器VM积极地改善了实时性能,使代码性能逐步提高其运行的时间越长。为了进行基准测试,HotSpot Client VM执行了很好的优化,并迅速达到了稳定状态,因此使我们能够快速开始测量性能。但是,我们仍然需要允许JIT编译器进行预热,因此我们必须忽略前几个较慢的执行(运行),否则将导致结果偏差。ScalaMeter本身可以很好地完成预热,但是要丢弃的运行次数是可配置的。
  2. JVM执行若干垃圾收集GC)周期,似乎是随机的,它可类似地降低性能,当他们出现。可以将ScalaMeter配置为忽略发生GC周期的执行
  3. 主机执行来自同一计算机上运行的其他进程的线程时,其负载可能会有所不同。这些也可能减慢执行时间。ScalaMeter通过考虑在固定数量的运行中仅观察到最快的时间来解决此问题,而不是取平均值。
  4. 如果从SBT运行,则分叉的JVM执行会话将比共享与SBT相同的JVM实例的会话执行得更好,并且变化较小(因为将使用更多的SBT JVM资源)。
  5. 虚拟内存页面错误(其中,将组成应用程序工作集的内存切换到页面文件或从页面文件切换到页面错误)也将随机影响性能。
  6. 许多函数的性能将取决于其参数(并且,如果您不喜欢函数式编程则应使用共享的互斥状态)。通过使用生成器,将性能与参数值绑定也是ScalaMeter擅长的(例如,考虑对进行操作,因为增加的元素数显然会花费更长的时间。)sizeListList
  7. 等等。您可以在《ScalaMeter入门指南》中找到有关这些问题的更多信息

显然,应该在同一台主机上执行基准测试,以使结果具有可比性,因为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()
      }
    }
  }
}

(顺便说一句:我本以为没有参数的基准测试函数会比这更直接,但这是到目前为止我能想到的最好的方法。如果有人有更好的主意,请添加注释并让我知道!)

因此,如果所有这些都是矫kill过正,那么您可能想要尝试这样的事情:

// 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()
}

您只需执行一次该函数,并且每次所用的时间将大不相同。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我可以在没有UncheckedException的情况下使用Collections.EMPTY_LIST吗?

我可以在没有粘性会话的情况下使用Thymeleaf模板+绑定吗?

我可以在没有jquery的情况下使用twitter bootstrap吗?

我可以在没有编译器的情况下使用JSPM吗?

我可以在没有RequireJS的情况下使用TypeScript吗?

我可以在没有Cargo.toml的情况下使用Cargo安装库吗?

我可以在没有Django的情况下使用芹菜吗

我们可以在没有OAuth的情况下使用Google youtube数据API吗?

我可以在没有任何实例变量的情况下使用decltype吗?

我可以在没有底层容器的情况下使用std :: upper_bound吗?

我可以在没有指针的情况下使用strcmp吗?

我可以在没有数据绑定的情况下使用MVVM吗?

我可以在没有任何WooCommerce页面的情况下使用WooCommerce功能吗?

我可以在没有activerecord的情况下使用超级堆栈吗?

我可以在没有线程的情况下使用pthread_sigmask吗?

我可以在没有PeerJS服务器的情况下使用PeerJS吗?

我可以在没有引导CSS的情况下使用fontawesome图标吗?

我们可以在没有雄辩的ORM的情况下使用Laravel表单绑定吗?

可以在没有分支的情况下使用git吗?

我可以在没有推送通知的情况下使用Scial.framework吗?

我可以在没有HealthKit的情况下使用ResearchKit吗?

我可以在没有JMS的情况下使用Camel和WMQ吗?

我可以在没有结构实例的情况下使用“ hana :: keys”吗?

我可以在没有 FCM 的情况下使用 ionic push native 吗?

我可以在没有 ob_start() 的情况下使用 ob_clean() 吗?

我可以在没有 ref 和 jnChange 的情况下使用表单输入吗?

我可以在没有 then() 或 await 的情况下使用 fs promise API 吗?

我可以在没有相应 getter 的情况下对 Java setter 使用属性语法吗?

可以在没有输入字段的情况下使用标签吗?