Some fixes in <perf> to make it stable

This commit is contained in:
Igor Chevdar
2018-04-10 17:48:08 +05:00
parent e8384f92fb
commit 1d0e9e7a67
5 changed files with 56 additions and 24 deletions
+19 -8
View File
@@ -19,8 +19,8 @@ repositories {
} }
//TODO: property //TODO: property
def ringWarmup=1000 def jvmWarmup = 10000
def iterations=2000 def nativeWarmup = 10
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'application' apply plugin: 'application'
@@ -31,10 +31,17 @@ checkKonanCompiler.dependsOn ':dist'
konanArtifacts { konanArtifacts {
program('Ring') { program('Ring') {
srcDir 'src/main/kotlin'
srcDir 'src/main/kotlin-native'
enableOptimizations true enableOptimizations true
} }
} }
sourceSets {
main.kotlin.srcDir 'src/main/kotlin'
main.kotlin.srcDir 'src/main/kotlin-jvm'
}
compileKotlin { compileKotlin {
kotlinOptions.suppressWarnings = true kotlinOptions.suppressWarnings = true
kotlinOptions { kotlinOptions {
@@ -51,7 +58,7 @@ task jvmRun(type: JavaExec) {
def output = new ByteArrayOutputStream() def output = new ByteArrayOutputStream()
classpath sourceSets.main.runtimeClasspath classpath sourceSets.main.runtimeClasspath
main = "MainKt" main = "MainKt"
args "$ringWarmup", "$iterations" args "$jvmWarmup"
standardOutput = output standardOutput = output
doLast { doLast {
dumpReport('jvmReport', output) dumpReport('jvmReport', output)
@@ -67,7 +74,7 @@ private void dumpReport(String name, ByteArrayOutputStream output) {
task konanRun(type: Exec) { task konanRun(type: Exec) {
dependsOn 'build' dependsOn 'build'
def output = new ByteArrayOutputStream() def output = new ByteArrayOutputStream()
commandLine konanArtifacts.Ring.getByTarget('host').artifact.absolutePath, "$ringWarmup", "$iterations" commandLine konanArtifacts.Ring.getByTarget('host').artifact.absolutePath, "$nativeWarmup"
standardOutput = output standardOutput = output
doLast { doLast {
dumpReport('konanReport', output) dumpReport('konanReport', output)
@@ -86,24 +93,28 @@ task bench(type:DefaultTask) {
def jvmReport = new Report(project.file("build/jvmReport.txt")) def jvmReport = new Report(project.file("build/jvmReport.txt"))
def konanReport = new Report(project.file("build/konanReport.txt")) def konanReport = new Report(project.file("build/konanReport.txt"))
def average = "none" def average = "none"
def absoluteAverage = "none"
jvmReport.report.each { k, v -> jvmReport.report.each { k, v ->
def ratio = String.format('%.2f', konanReport.report[k]/v * 100) def konanValue = konanReport.report[k]
def ratio = String.format('%.2f', konanValue/v)
def formattedKonanValue = String.format('%.2f', konanValue/1000)
if (k == 'RingAverage') { if (k == 'RingAverage') {
average = ratio average = ratio
absoluteAverage = formattedKonanValue
} }
println("$k : $ratio %") println("$k : absolute = $formattedKonanValue us, ratio = $ratio")
if (System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") != null) if (System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") != null)
println("##teamcity[buildStatisticValue key='$k' value='$ratio']") println("##teamcity[buildStatisticValue key='$k' value='$ratio']")
} }
println() println()
println("Average Ring score: $average %") println("Average Ring score: absolute = $absoluteAverage us, ratio = $average")
} }
} }
class Report { class Report {
def Map<String, Double> report = new HashMap() def Map<String, Double> report = new TreeMap()
Report(File path) { Report(File path) {
path.readLines().drop(3).findAll { it.split(':').length == 2 }.each { path.readLines().drop(3).findAll { it.split(':').length == 2 }.each {
@@ -0,0 +1,3 @@
package org.jetbrains.ring
fun cleanup() { }
@@ -0,0 +1,5 @@
package org.jetbrains.ring
import konan.internal.GC
fun cleanup() { GC.collect() }
+2 -6
View File
@@ -18,15 +18,11 @@ import org.jetbrains.ring.Launcher
fun main(args: Array<String>) { fun main(args: Array<String>) {
var numWarmIterations = 0 // Should be 100000 for jdk based run var numWarmIterations = 0 // Should be 100000 for jdk based run
var numMeasureIterations = 2000
if (args.size == 2) { if (args.size == 1)
numWarmIterations = args[0].toInt() numWarmIterations = args[0].toInt()
numMeasureIterations = args[1].toInt()
}
println("Ring starting") println("Ring starting")
println(" warmup iterations count: $numWarmIterations") println(" warmup iterations count: $numWarmIterations")
println(" measure iterations count: $numMeasureIterations") Launcher(numWarmIterations).runBenchmarks()
Launcher(numWarmIterations, numMeasureIterations).runBenchmarks()
} }
@@ -23,21 +23,38 @@ val BENCHMARK_SIZE = 100
//-----------------------------------------------------------------------------// //-----------------------------------------------------------------------------//
class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) { class Launcher(val numWarmIterations: Int) {
val results = mutableMapOf<String, Long>() val results = mutableMapOf<String, Long>()
fun launch(benchmark: () -> Any?, coeff: Double = 1.0): Long { // If benchmark runs too long - use coeff to speed it up. fun launch(benchmark: () -> Any?): Long { // If benchmark runs too long - use coeff to speed it up.
var i = (numWarmIterations * coeff).toInt() var i = numWarmIterations
var j = (numMeasureIterations * coeff).toInt()
while (i-- > 0) benchmark() while (i-- > 0) benchmark()
val time = measureNanoTime { cleanup()
while (j-- > 0) {
benchmark() var autoEvaluatedNumberOfMeasureIteration = 1
while (true) {
var j = autoEvaluatedNumberOfMeasureIteration
val time = measureNanoTime {
while (j-- > 0) {
benchmark()
}
cleanup()
} }
if (time >= 100L * 1_000_000) // 100ms
break
autoEvaluatedNumberOfMeasureIteration *= 2
} }
return (time / numMeasureIterations / coeff).toLong() i = autoEvaluatedNumberOfMeasureIteration
val time = measureNanoTime {
while (i-- > 0) {
benchmark()
}
cleanup()
}
return time / autoEvaluatedNumberOfMeasureIteration
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
@@ -85,7 +102,7 @@ class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) {
fun printResultsNormalized() { fun printResultsNormalized() {
var total = 0.0 var total = 0.0
results.forEach { results.asSequence().sortedBy { it.key }.forEach {
val normaTime = NormaResults[it.key] val normaTime = NormaResults[it.key]
if (normaTime == null) println("ERROR: no norma for benchmark ${it.key}") if (normaTime == null) println("ERROR: no norma for benchmark ${it.key}")
@@ -436,7 +453,7 @@ class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) {
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun runOctoTest() { fun runOctoTest() {
results["OctoTest"] = launch(::octoTest, 0.1) results["OctoTest"] = launch(::octoTest)
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//