我可以在没有输入的情况下使用ScalaMeter吗? [英] Can I use ScalaMeter with no input?

查看:105
本文介绍了我可以在没有输入的情况下使用ScalaMeter吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to benchmark the runtime of several methods in my Scala application, and I am looking into using ScalaMeter. Let's say I want to measure the time of a method called doSomething().

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

I only want to call doSomething and measure the time it takes to run once. However all of the documentation I see for ScalaMeter requires providing some kind of input, whether it is a series of integers, a string, or something.

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

Is it possible to use ScalaMeter to do what I am asking? Is it an appropriate use case?

推荐答案

可以,但是会浪费时间.

It is possible, but it would be a waste of time.

您可能已经知道, ScalaMeter 旨在消除函数执行时间变化的影响,从而可以准确地对那些执行时间进行基准测试.例如,您可能想验证功能是否在规定的时间内完成,或者确定随着代码库的更改,其性能是否会随着时间的推移而得以保持.

As you're probably aware, ScalaMeter is designed to remove the effects of variation in function execution times, so that it's possible to accurately benchmark those execution times. For example, you might want to verify that a function completes within a required time, or to determine whether its performance is maintained over time as changes are made to the code base.

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

Why is that so challenging? Well, there's a number of obstacles to overcome:

  1. JVM 具有许多不同的选项,用于在程序中执行生成的 Java字节码.有些(例如 Zero VM )只是解释代码.其他人则利用及时( JIT )编译来优化对主机CPU的机器代码的转换; HotSpot Server VM 会随着时间的推移积极地提高性能,从而使代码性能随着运行时间的延长而逐步提高.为了进行基准测试, HotSpot Client VM 进行了很好的优化,并迅速达到了稳定状态,因此使我们能够快速开始评估性能.但是,我们仍然需要允许 JIT 编译器进行预热,因此我们必须忽略前几个执行速度较慢的执行程序( runs ),否则它们会影响我们的结果. ScalaMeter 本身可以很好地完成 warmup 的工作,但是要丢弃的运行次数是可配置的.
  2. JVM 执行许多垃圾回收( GC )周期,看似随机,这在发生时同样会降低性能.可以将 ScalaMeter 配置为忽略发生 GC 循环的执行.
  3. 主机执行来自同一计算机上运行的其他进程的线程时,其负载可能会有所不同.这些也可能减慢执行时间. ScalaMeter 通过仅考虑固定运行次数中观察到的最快时间来解决此问题,而不是取平均值.
  4. 如果您是从 SBT 运行的,那么与共享相同 JVM 实例作为 SBT (因为将使用更多的 SBT JVM 资源).
  5. 虚拟内存页面错误(其中,将构成应用程序工作集的内存与分页文件切换)随机影响性能.
  6. 许多函数的性能将取决于其参数(并且,如果您不喜欢功能编程,则是共享的互斥状态).通过使用 generators ,将性能与参数值绑定也是 ScalaMeter 的优势. (例如,考虑在List上执行size操作-随着List中元素数量的增加,执行时间显然会更长.)
  7. 等等您可以在 ScalaMeter入门指南中找到更多有关这些问题的信息./em>.
  1. The JVM has a number of different options for executing the resulting Java bytecode in a program. Some (such as the Zero VM) just interprets code; others utilize just-in-time (JIT) compilation to optimize translation into the host CPU's machine code; the HotSpot Server VM aggressively improves performance over time, so that code performance incrementally improves the longer it runs. For benchmarking purposes, the HotSpot Client VM performs very good optimization and reaches a steady-state quickly, which therefore allows us to start measuring performance rapidly. However, we still need to allow the JIT compiler to warm up, and so we must disregard the first few, slower executions (runs) that would otherwise bias our results. ScalaMeter does a pretty good job of undertaking this warmup by itself, but the number of runs to be discarded is configurable.
  2. The JVM performs a number of garbage collection (GC) cycles, seemingly at random, which can similarly slow down performance when they occur. ScalaMeter can be configured to ignore executions in which GC cycles occurred.
  3. The host machine's load can vary as it executes threads from other processes running on the same machine. These also potentially slow down execution times. ScalaMeter deals with this by considering only the fastest observed time in a fixed number of runs, rather than by taking an average.
  4. If you're running from SBT, a forked JVM execution session will perform better, and with less variation, than one that shares the same JVM instance as SBT (because more of the SBT JVM's resources will be in use).
  5. Virtual memory page faults (in which the memory making up the application's working set is switched to/from a paging file) will also randomly impact performance.
  6. The performance of many functions will depend upon its arguments (and, if you're not into functional programming, shared mutual state). Tying performance to argument values is also something ScalaMeter is good at, through it's use of generators. (For example, consider a size operation on a List—it will clearly take longer to execute as the number of elements in the List increases.)
  7. Etc. You can find more on these issues in the ScalaMeter Getting Started Introduction.

很明显,基准测试应该在同一台主机上执行,以使结果具有可比性,因为CPU,操作系统,内存,BIOS配置等也都会影响性能.

Clearly, benchmarks should be performed on the same host machine so that the results are comparable, since CPU, OS, Memory, BIOS Config, etc. all affect performance too.

因此,在解释了所有这些内容之后,您将理解为什么 ScalaMeter 需要多次执行相同的功能!;-)

So, having explained all that, you will understand why ScalaMeter needs to execute the same function a lot! ;-)

在您的情况下,doSomething()不带任何参数,因此可以使用Gen[T].single生成器来标识doSomething()所属的类或对象,其外观类似于以下内容:

In your case, doSomething() takes no arguments, so you can use a Gen[T].single generator that identifies the class or object to which doSomething() belongs, which will look something like the following:

注意:这是作为 ScalaMeter 测试编写的,因此源应位于src/test/scala下:

Note: This is written as a ScalaMeter test, and so the source should be under 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()
      }
    }
  }
}

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

(BTW: I would have thought that benchmarking functions with no arguments would be more straightforward than this, but this is the best I've been able to come up with so far. If anyone has a better idea, please add a comment and let me know!)

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

So, if all of that is overkill, you might want to try something like this:

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

您将只执行一次该功能,并且每次所用的时间将大不相同.

You'll only execute the function once, and the time taken will be wildly different each time.

这篇关于我可以在没有输入的情况下使用ScalaMeter吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆