我为使用动态编程找出最长公共子序列的方法创建了一个基准:
@Benchmark
def longestCommonSubsequenceDP(): String = {
val s1 = "Pellentesque lacinia"
val s2 = "Mauris purus massa"
val up = 1
val left = 2
val charMatched = 3
val s1Length = s1.length()
val s2Length = s2.length()
val lcsLengths = Array.fill[Int](s1Length + 1, s2Length + 1)(0)
for (i <- 0 until s1Length) {
for (j <- 0 until s2Length) {
if (s1.charAt(i) == s2.charAt(j)) {
lcsLengths(i + 1)(j + 1) = lcsLengths(i)(j) + 1
} else {
if (lcsLengths(i)(j + 1) >= lcsLengths(i + 1)(j)) {
lcsLengths(i + 1)(j + 1) = lcsLengths(i)(j + 1)
} else {
lcsLengths(i + 1)(j + 1) = lcsLengths(i + 1)(j)
}
}
}
}
val subSeq = new StringBuilder()
var s1Pos = s1Length
var s2Pos = s2Length
do {
if (lcsLengths(s1Pos)(s2Pos) == lcsLengths(s1Pos -1)(s2Pos)) {
s1Pos -= 1
} else if (lcsLengths(s1Pos)(s2Pos) == lcsLengths(s1Pos)(s2Pos - 1)) {
s2Pos -= 1
} else {
assert(s1.charAt(s1Pos - 1) == s2.charAt(s2Pos - 1))
subSeq += s1.charAt(s1Pos - 1)
s1Pos -= 1
s2Pos -= 1
}
} while (s1Pos > 0 && s2Pos > 0)
subSeq.toString.reverse
}
并使用以下配置运行它jmh:run -i 10 -wi 10 -f1 -t1
并得到以下结果:
GraalVM EE 1.0.0-rc10
[info] Benchmark Mode Cnt Score Error Units
[info] LCS.longestCommonSubsequenceDP thrpt 25 91.411 ± 4.355 ops/ms
GraalVM CE 1.0.0-rc10
[info] Benchmark Mode Cnt Score Error Units
[info] LCS.longestCommonSubsequenceDP thrpt 25 26.741 ± 0.408 ops/ms
OpenJDK 1.8.0_192
[info] Benchmark Mode Cnt Score Error Units
[info] LCS.longestCommonSubsequenceDP thrpt 25 45.216 ± 1.956 ops/ms
我还做了另一个测试,我创建了一个包含数千个对象的列表,对其进行了一些过滤和排序,并且thrpt
在 GraalVM CE 上是最小的。
为什么会有这种差异?