如何使用文件中的数据进行微基准测试?

How to Microbenchmark using data from a file?

我正在尝试对使用 Scalameter 计算 运行 中位数的两种不同实现进行微基准测试。我有一些测试文件,大小不一,这些文件将来自这些文件。问题是,以下代码立即完成,根本没有生成任何类型的基准。

object MedianMaintenanceBenchmark extends Bench[Double] {

  /* configuration */

  lazy val executor = LocalExecutor(
    new Warmer.Default,
    Aggregator.median[Double],
    measurer
  )
  lazy val measurer = new Measurer.Default
  lazy val reporter = new LoggingReporter[Double]
  lazy val persistor: Persistor.None.type = Persistor.None

  /* inputs */

  private val files: Gen[String] = Gen.enumeration("files")("median-test")
  private val num: Gen[Seq[Int]] = (for (f <- files) yield numbers(f)).cached

  /* tests */

  performance of "MedianMaintenance" config (
    exec.benchRuns -> 10
    ) in {
    measure method "using heap" in {
      using(num) in {
        xs => MedianMaintenanceUsingHeaps(xs).medians
      }
    }
  }

  private def numbers(filename: String): Seq[Int] = // elided
}

输出:

::Benchmark MedianMaintenance.using heap::
cores: 8
hostname: ***
name: OpenJDK 64-Bit Server VM
osArch: x86_64
osName: Mac OS X
vendor: Azul Systems, Inc.
version: 11.0.1+13-LTS
Parameters(files -> median-test): 3.612799 ms

这是怎么回事?

编辑:

按如下所示更改代码至少会有所作为,但不支持选项。好像是运行文件'Median'一共测试了18次,不是3+10的总和。

object MedianMaintenanceBenchmark extends Bench.ForkedTime {

  /* configuration */
  override def aggregator: Aggregator[Double] = Aggregator.median

  private val opts = Context(
    exec.minWarmupRuns-> 3,
    exec.maxWarmupRuns -> 3,
    exec.benchRuns -> 10,
    exec.jvmflags -> List("-Xms2g", "-Xmx2g")
  )

  /* inputs */

  private val files: Gen[String] = Gen.enumeration("files")("median-test", "Median")
  private val num: Gen[Seq[Int]] = (for (f <- files) yield numbers(f)).cached

  /* tests */

  performance of "MedianMaintenance" config opts in {
    measure method "using heap" in {
      using(num) in {
        xs => MedianMaintenanceUsingHeaps(xs).medians
      }
    }

    measure method "using red-black BST" in {
      using(num) in {
        xs => MedianMaintenanceUsingRedBlackTree(xs).medians
      }
    }
  }

  private def numbers(filename: String): Seq[Int] = // elided
}

OP 在这里:几个小时后,我终于能够通过可悲的过时文档,无论如何都存在,并弄清楚以下内容:

除了我上面的编辑之外,还有几种方法可以覆盖执行计数等。其他

  1. 对于当前文件中的所有基准,使用override def defaultConfig: Context = Context(exec.benchRuns -> 10)
  2. 对于特定基准,定义内联或定义 val opts: Context 并使用 config opts in DSL。
  3. 对于特定方法,除了在方法 DSL 中使用 config opts in 外,与 #2 相同。
  4. 文档声称可以覆盖每个 "curve" 的配置,但我无法找到 "curve" 是什么或如何覆盖它的配置。

independentSamples = 生成的独立 JVM 数。

使用一组测试数据(随机选择?)在每个 JVM 上进行 运行 (minWarmupRuns to maxWarmupRuns) 次预热(有意义),然后在每个 JVM 上进行 运行 次测试benchRuns 次。 运行 有多少预热取决于 "steady state" 的检测。每个JVM最后似乎有一个执行下落不明。

Total number of executions = independentSamples * ((minWarmupRuns to maxWarmupRuns) + benchRuns + 1)

例如,给定:

Context(
  exec.minWarmupRuns -> 5,
  exec.maxWarmupRuns -> 5,
  exec.benchRuns -> 10,
  exec.independentSamples -> 2
)

将执行 32 次被测代码。