测试在Scala中填充序列与列表的性能时出现的问题

测试在Scala中填充序列与列表的性能时出现的问题,scala,scala-collections,Scala,Scala Collections,我一直在努力了解在Scala中选择Seq或List的基本原理,为了帮助理解这一点,我正在尝试创建一个简单的定时示例,其中我为每个示例创建一个实例,两个实例都填充了相同数量的元素-见下文 object SeqVsList extends App with LazyLogging { private val numberOfElements = 1234567 // whichever of these is run first takes the most amount of time

我一直在努力了解在Scala中选择Seq或List的基本原理,为了帮助理解这一点,我正在尝试创建一个简单的定时示例,其中我为每个示例创建一个实例,两个实例都填充了相同数量的元素-见下文

object SeqVsList extends App with LazyLogging {

  private val numberOfElements = 1234567

  // whichever of these is run first takes the most amount of time
  populateSeq()
  populateList()

  def populateSeq(): Unit = {
    val seqStartTime = System.currentTimeMillis()
    val aSeq = Seq.fill(numberOfElements)("foo")
    logger.info(s"Populating Seq took ${System.currentTimeMillis() - seqStartTime} ms")
  }

  def populateList(): Unit = {
    val listStartTime = System.currentTimeMillis()
    val aList = List.fill(numberOfElements)("bar")
    logger.info(s"Populating List took ${System.currentTimeMillis() - listStartTime} ms")
  }
}
我遇到的问题(正如我在代码中的注释中所定义的)是,这个示例不能准确地表示哪一个填充所有元素最快,而我首先调用的方法总是最慢的


我想在幕后会发生一些事情,比如在运行时将一堆对象加载到内存中,这会减慢两种方法中的第一种?如果有人能帮我阐明这一点,我将非常感激。

我刚刚试着用sbt jmh的一些基准测试来证明等式Seq和List的概念:

package bmks

import java.util.concurrent.TimeUnit

import org.openjdk.jmh.annotations.{Benchmark, OutputTimeUnit}

@OutputTimeUnit(TimeUnit.MILLISECONDS)
class TestBenchmark {

  @Benchmark
  def seq(): Seq[String] =
    Seq.fill(1234567)("foo")

  @Benchmark
  def list(): Seq[String] =
    List.fill(1234567)("foo")
}
使用以下命令运行它:

$ sbt 
$ sbt:benchmarks> jmh:run -i 20 -wi 10 -f1 -t1
得到:

sbt:benchmarks> jmh:run -i 20 -wi 10 -f1 -t1
[info] Compiling 1 Scala source to /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/classes ...
[info] Done compiling.
[info] Packaging /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/benchmarks_2.12-1.0.jar ...
Processing 1 classes from /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/classes with "reflection" generator
Writing out Java source to /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/src_managed/jmh and resources to /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/resource_managed/jmh
[info] Done packaging.
[info] Compiling 6 Java sources to /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/classes ...
[info] Done compiling.
[info] Packaging /Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/benchmarks_2.12-1.0-jmh.jar ...
[info] Done packaging.
[info] Running (fork) org.openjdk.jmh.Main -i 20 -wi 10 -f1 -t1
[info] # JMH version: 1.21
[info] # VM version: JDK 1.8.0_161, Java HotSpot(TM) 64-Bit Server VM, 25.161-b12
[info] # VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/bin/java
[info] # VM options: <none>
[info] # Warmup: 10 iterations, 10 s each
[info] # Measurement: 20 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread, will synchronize iterations
[info] # Benchmark mode: Throughput, ops/time
[info] # Benchmark: bmks.TestBenchmark.list
[info] # Run progress: 0.00% complete, ETA 00:10:00
[info] # Fork: 1 of 1
[info] # Warmup Iteration   1: 0.091 ops/ms
[info] # Warmup Iteration   2: 0.111 ops/ms
[info] # Warmup Iteration   3: 0.111 ops/ms
[info] # Warmup Iteration   4: 0.113 ops/ms
[info] # Warmup Iteration   5: 0.112 ops/ms
[info] # Warmup Iteration   6: 0.115 ops/ms
[info] # Warmup Iteration   7: 0.114 ops/ms
[info] # Warmup Iteration   8: 0.116 ops/ms
[info] # Warmup Iteration   9: 0.115 ops/ms
[info] # Warmup Iteration  10: 0.115 ops/ms
[info] Iteration   1: 0.115 ops/ms
[info] Iteration   2: 0.116 ops/ms
[info] Iteration   3: 0.114 ops/ms
[info] Iteration   4: 0.114 ops/ms
[info] Iteration   5: 0.115 ops/ms
[info] Iteration   6: 0.114 ops/ms
[info] Iteration   7: 0.116 ops/ms
[info] Iteration   8: 0.115 ops/ms
[info] Iteration   9: 0.115 ops/ms
[info] Iteration  10: 0.115 ops/ms
[info] Iteration  11: 0.115 ops/ms
[info] Iteration  12: 0.115 ops/ms
[info] Iteration  13: 0.114 ops/ms
[info] Iteration  14: 0.116 ops/ms
[info] Iteration  15: 0.115 ops/ms
[info] Iteration  16: 0.115 ops/ms
[info] Iteration  17: 0.115 ops/ms
[info] Iteration  18: 0.114 ops/ms
[info] Iteration  19: 0.114 ops/ms
[info] Iteration  20: 0.117 ops/ms
[info] Result "bmks.TestBenchmark.list":
[info]   0.115 ±(99.9%) 0.001 ops/ms [Average]
[info]   (min, avg, max) = (0.114, 0.115, 0.117), stdev = 0.001
[info]   CI (99.9%): [0.114, 0.116] (assumes normal distribution)
[info] # JMH version: 1.21
[info] # VM version: JDK 1.8.0_161, Java HotSpot(TM) 64-Bit Server VM, 25.161-b12
[info] # VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/bin/java
[info] # VM options: <none>
[info] # Warmup: 10 iterations, 10 s each
[info] # Measurement: 20 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread, will synchronize iterations
[info] # Benchmark mode: Throughput, ops/time
[info] # Benchmark: bmks.TestBenchmark.seq
[info] # Run progress: 50.00% complete, ETA 00:05:01
[info] # Fork: 1 of 1
[info] # Warmup Iteration   1: 0.094 ops/ms
[info] # Warmup Iteration   2: 0.115 ops/ms
[info] # Warmup Iteration   3: 0.118 ops/ms
[info] # Warmup Iteration   4: 0.115 ops/ms
[info] # Warmup Iteration   5: 0.114 ops/ms
[info] # Warmup Iteration   6: 0.115 ops/ms
[info] # Warmup Iteration   7: 0.115 ops/ms
[info] # Warmup Iteration   8: 0.115 ops/ms
[info] # Warmup Iteration   9: 0.114 ops/ms
[info] # Warmup Iteration  10: 0.117 ops/ms
[info] Iteration   1: 0.116 ops/ms
[info] Iteration   2: 0.116 ops/ms
[info] Iteration   3: 0.089 ops/ms
[info] Iteration   4: 0.116 ops/ms
[info] Iteration   5: 0.116 ops/ms
[info] Iteration   6: 0.118 ops/ms
[info] Iteration   7: 0.116 ops/ms
[info] Iteration   8: 0.118 ops/ms
[info] Iteration   9: 0.118 ops/ms
[info] Iteration  10: 0.117 ops/ms
[info] Iteration  11: 0.117 ops/ms
[info] Iteration  12: 0.107 ops/ms
[info] Iteration  13: 0.111 ops/ms
[info] Iteration  14: 0.113 ops/ms
[info] Iteration  15: 0.113 ops/ms
[info] Iteration  16: 0.114 ops/ms
[info] Iteration  17: 0.114 ops/ms
[info] Iteration  18: 0.114 ops/ms
[info] Iteration  19: 0.114 ops/ms
[info] Iteration  20: 0.114 ops/ms
[info] Result "bmks.TestBenchmark.seq":
[info]   0.114 ±(99.9%) 0.005 ops/ms [Average]
[info]   (min, avg, max) = (0.089, 0.114, 0.118), stdev = 0.006
[info]   CI (99.9%): [0.108, 0.119] (assumes normal distribution)
[info] # Run complete. Total time: 00:10:02
[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] Benchmark            Mode  Cnt  Score   Error   Units
[info] TestBenchmark.list  thrpt   20  0.115 ± 0.001  ops/ms
[info] TestBenchmark.seq   thrpt   20  0.114 ± 0.005  ops/ms
[success] Total time: 607 s, completed Apr 29, 2019 8:35:22 PM

sbt:benchmarks>jmh:run-i20-wi10-f1-t1
[信息]正在将1个Scala源代码编译为/Volumes/AuroraHD/DEV/Scala/benchmarks/target/Scala-2.12/classes。。。
[信息]完成编译。
[info]Packaging/Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/benchmarks_2.12-1.0.jar。。。
使用“反射”生成器处理/Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/classes中的1个类
将Java源代码写入/Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/src_managed/jmh,将资源写入/Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/resource_managed/jmh
[信息]完成包装。
[信息]正在将6个Java源代码编译为/Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/classes。。。
[信息]完成编译。
[info]Packaging/Volumes/AuroraHD/DEV/scala/benchmarks/target/scala-2.12/benchmarks_2.12-1.0-jmh.jar。。。
[信息]完成包装。
[info]Running(fork)org.openjdk.jmh.Main-i20-wi10-f1-t1
[信息]#JMH版本:1.21
[信息]#虚拟机版本:JDK 1.8.0_161,Java HotSpot(TM)64位服务器虚拟机,25.161-b12
[信息]#虚拟机调用程序:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/bin/Java
[信息]#虚拟机选项:
[信息]#预热:10次迭代,每次10秒
[信息]#测量:20次迭代,每次10秒
[信息]#超时:每次迭代10分钟
[信息]#线程:1个线程,将同步迭代
[信息]#基准模式:吞吐量、运营/时间
[信息]#基准:bmks.TestBenchmark.list
[信息]#运行进度:完成0.00%,预计时间00:10:00
[信息]#Fork:1/1
[信息]#预热迭代1:0.091 ops/ms
[信息]#预热迭代2:0.111次/ms
[信息]#预热迭代3:0.111次/ms
[信息]#预热迭代4:0.113次/秒
[信息]#预热迭代5:0.112次/毫秒
[信息]#预热迭代6:0.115次/ms
[信息]#预热迭代7:0.114次/ms
[信息]#预热迭代8:0.116次/ms
[信息]#预热迭代9:0.115次/秒
[信息]#预热迭代10:0.115次/秒
[信息]迭代1:0.115次/ms
[信息]迭代2:0.116次/ms
[信息]迭代3:0.114次/ms
[信息]迭代4:0.114次/ms
[信息]迭代5:0.115 ops/ms
[信息]迭代6:0.114次/ms
[信息]迭代7:0.116 ops/ms
[信息]迭代8:0.115次/ms
[信息]迭代9:0.115 ops/ms
[信息]迭代10:0.115 ops/ms
[信息]迭代11:0.115 ops/ms
[信息]迭代12:0.115 ops/ms
[信息]迭代13:0.114次/ms
[信息]迭代14:0.116 ops/ms
[信息]迭代15:0.115次/ms
[信息]迭代16:0.115次/ms
[信息]迭代17:0.115 ops/ms
[信息]迭代18:0.114次/ms
[信息]迭代19:0.114次/ms
[信息]迭代20:0.117 ops/ms
[信息]结果“bmks.TestBenchmark.list”:
[信息]0.115±(99.9%)0.001次/ms[平均]
[信息](最小值、平均值、最大值)=(0.114、0.115、0.117),标准差=0.001
[信息]CI(99.9%):[0.114,0.116](假设为正态分布)
[信息]#JMH版本:1.21
[信息]#虚拟机版本:JDK 1.8.0_161,Java HotSpot(TM)64位服务器虚拟机,25.161-b12
[信息]#虚拟机调用程序:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/bin/Java
[信息]#虚拟机选项:
[信息]#预热:10次迭代,每次10秒
[信息]#测量:20次迭代,每次10秒
[信息]#超时:每次迭代10分钟
[信息]#线程:1个线程,将同步迭代
[信息]#基准模式:吞吐量、运营/时间
[信息]#基准:bmks.TestBenchmark.seq
[信息]#运行进度:完成50.00%,预计时间00:05:01
[信息]#Fork:1/1
[信息]#预热迭代1:0.094 ops/ms
[信息]#预热迭代2:0.115次/秒
[信息]#预热迭代3:0.118次/秒
[信息]#预热迭代4:0.115次/秒
[信息]#预热迭代5:0.114次/ms
[信息]#预热迭代6:0.115次/ms
[信息]#预热迭代7:0.115次/秒
[信息]#预热迭代8:0.115次/秒
[信息]#预热迭代9:0.114次/ms
[信息]#预热迭代10:0.117次/ms
[信息]迭代1:0.116次/ms
[信息]迭代2:0.116次/ms
[信息]迭代3:0.089 ops/ms
[信息]迭代4:0.116 ops/ms
[信息]迭代5:0.116次/ms
[信息]迭代6:0.118次/ms
[信息]迭代7:0.116 ops/ms
[信息]迭代8:0.118次/毫秒
[信息]迭代9:0.118次/ms
[信息]迭代10:0.117 ops/ms
[信息]迭代11:0.117 ops/ms
[信息]迭代12:0.107 ops/ms
[信息]迭代13:0.111次/ms
[信息]迭代14:0.113 ops/ms
[信息]迭代15:0.113次/毫秒
[信息]迭代16:0.114次/ms
[信息]迭代17:0.114次/ms
[信息]迭代18:0.114次/ms
[信息]迭代19:0.114次/ms
[信息]迭代20:0.114次/ms
[信息]结果“bmks.TestBenchmark.seq”:
[信息]0.114±(99.9%)0.005 ops/ms[平均]
[信息](最小值、平均值、最大值)=(0.089、0.114、0.118),标准差=0.006
[信息]CI(99.9%):[0.108,0.119](假设为正态分布)
[信息]#运行完成。总时间:00:10:02
[信息]记住:下面的数字只是数据。要获得可重用的见解,您需要跟进
[信息]为什么数字是这样的。使用分析器(参见-prof,-lprof),des