Schema update (organising benchmarks within projects)
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
export PHOEBENCH_BUILD_RELEASE='true'
|
||||||
|
|
||||||
./gradlew :clients:cli:shadowJar
|
./gradlew :clients:cli:shadowJar
|
||||||
./gradlew :clients:compose:createDistributable
|
./gradlew :clients:compose:createDistributable
|
||||||
./gradlew :clients:compose:wasmJsBrowserProductionWebpack
|
./gradlew :clients:compose:wasmJsBrowserProductionWebpack
|
||||||
|
|||||||
@@ -158,3 +158,24 @@ fun envValue(key: String): String? {
|
|||||||
.firstOrNull { it.first == key }?.second
|
.firstOrNull { it.first == key }?.second
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildConfig {
|
||||||
|
generateAtSync = false
|
||||||
|
useKotlinOutput { internalVisibility = false }
|
||||||
|
|
||||||
|
println("Source sets: ${kotlin.sourceSets.toList().map { it.name }}")
|
||||||
|
|
||||||
|
sourceSets.named("desktopMain") {
|
||||||
|
println("Generating 'desktopMain'")
|
||||||
|
className("PersistenceConstants")
|
||||||
|
packageName("com.jaytux.phoebench.clients")
|
||||||
|
|
||||||
|
envValue("PHOEBENCH_BUILD_RELEASE")?.let {
|
||||||
|
println("Using release desktop service")
|
||||||
|
buildConfigField("SERVICE", "com.jaytux.phoebench")
|
||||||
|
} ?: run {
|
||||||
|
println("Using debug desktop service")
|
||||||
|
buildConfigField("SERVICE", "com.jaytux.phoebench.debug")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import kotlinx.datetime.format.Padding
|
|||||||
import kotlinx.datetime.format.char
|
import kotlinx.datetime.format.char
|
||||||
import kotlinx.datetime.toLocalDateTime
|
import kotlinx.datetime.toLocalDateTime
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
import kotlin.math.pow
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.nextInt
|
import kotlin.random.nextInt
|
||||||
@@ -138,3 +139,9 @@ fun <T1, T2, T3, T4> List<Tuple4<T1, T2, T3, T4>>.unzip(): Tuple4<List<T1>, List
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T> List<T>.removeAt(idx: Int): List<T> = subList(0, idx) + subList(idx + 1, size)
|
fun <T> List<T>.removeAt(idx: Int): List<T> = subList(0, idx) + subList(idx + 1, size)
|
||||||
|
|
||||||
|
fun List<Float>.geomean(): Float {
|
||||||
|
var prod = 1.0f
|
||||||
|
for(value in this) prod *= value
|
||||||
|
return prod.pow(1.0f / size.toFloat())
|
||||||
|
}
|
||||||
+26
-12
@@ -509,6 +509,8 @@ fun ProjectPlotArea(vm: ProjectVM, benchmark: ProjectVM.Benchmark) {
|
|||||||
val allInputs by vm.inputs
|
val allInputs by vm.inputs
|
||||||
val allHardware by vm.hardware
|
val allHardware by vm.hardware
|
||||||
|
|
||||||
|
val visibleInputs by remember(entries, allInputs) { mutableStateOf(allInputs intersect entries.map { it.input }.toSet()) }
|
||||||
|
|
||||||
var filteredEntries by remember { mutableStateOf(entries) }
|
var filteredEntries by remember { mutableStateOf(entries) }
|
||||||
var timeMin by remember { mutableStateOf(Instant.DISTANT_PAST) }
|
var timeMin by remember { mutableStateOf(Instant.DISTANT_PAST) }
|
||||||
var timeMax by remember { mutableStateOf(Instant.DISTANT_FUTURE) }
|
var timeMax by remember { mutableStateOf(Instant.DISTANT_FUTURE) }
|
||||||
@@ -587,21 +589,33 @@ fun ProjectPlotArea(vm: ProjectVM, benchmark: ProjectVM.Benchmark) {
|
|||||||
LaunchedEffect(filteredEntries, baseline, currentUnit) {
|
LaunchedEffect(filteredEntries, baseline, currentUnit) {
|
||||||
var max = 0.0f
|
var max = 0.0f
|
||||||
baselineComparison = baseline?.let { bl ->
|
baselineComparison = baseline?.let { bl ->
|
||||||
val perVersion = mutableMapOf<ProjectVM.Version, Pair<Float, Float>>()
|
class MeanAccumulator(var sum: Float = 0.0f, var count: Float = 0.0f) {
|
||||||
|
fun add(f: Float) { sum += f; count += 1.0f }
|
||||||
|
fun mean() = if(count == 0.0f) 0.0f else sum / count
|
||||||
|
}
|
||||||
|
val perVersion = mutableMapOf<ProjectVM.Version, MutableMap<String, MeanAccumulator>>()
|
||||||
filteredEntries.forEach { entry ->
|
filteredEntries.forEach { entry ->
|
||||||
val corrected = entry.measurements.map { entry.nativeUnit.convertTo(currentUnit, it) }.sum()
|
val corrected = entry.measurements.map { entry.nativeUnit.convertTo(currentUnit, it) }.sum()
|
||||||
perVersion[entry.label] = perVersion[entry.label]?.let {
|
perVersion.getOrPut(entry.label) { mutableMapOf() }
|
||||||
(previous, prCount) -> (previous + corrected) to (prCount + entry.measurements.size)
|
.getOrPut(entry.input) { MeanAccumulator() }
|
||||||
} ?: (corrected to entry.measurements.size.toFloat())
|
.add(corrected)
|
||||||
}
|
}
|
||||||
|
|
||||||
val means = perVersion.mapValues { (_, v) -> v.first / v.second }
|
val subMeans = perVersion.mapValues { (_, v) -> v.mapValues { (_, acc) -> acc.mean() } }
|
||||||
val baselineData = means[bl] ?: return@let null
|
val baseline = subMeans[bl] ?: return@let null
|
||||||
means.mapNotNull { (ver, data) ->
|
|
||||||
val speedup = baselineData / data
|
val versionSpeedups = subMeans.mapValues { (_, v) ->
|
||||||
max = maxOf(max, speedup)
|
v.mapNotNull { (input, mean) ->
|
||||||
ver.name to speedup app ver.uiColor app data
|
val base = baseline[input] ?: return@mapNotNull null
|
||||||
|
(base / mean) to mean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
versionSpeedups.mapNotNull { (version, inputMeans) ->
|
||||||
|
val speedup = inputMeans.map { it.first }.geomean()
|
||||||
|
max = maxOf(max, speedup)
|
||||||
|
version.name to speedup app version.uiColor app inputMeans.map { it.second }.geomean()
|
||||||
|
}.sortedBy { it.t1 }
|
||||||
}
|
}
|
||||||
baselineMax = max
|
baselineMax = max
|
||||||
}
|
}
|
||||||
@@ -775,7 +789,7 @@ fun ProjectPlotArea(vm: ProjectVM, benchmark: ProjectVM.Benchmark) {
|
|||||||
|
|
||||||
item { Spacer(Modifier.height(10.dp)) }
|
item { Spacer(Modifier.height(10.dp)) }
|
||||||
|
|
||||||
items((allInputs intersect inputFilter.toSet()).toList()) {
|
items((visibleInputs intersect inputFilter.toSet()).toList()) {
|
||||||
Row(Modifier.fillMaxWidth().clickable {
|
Row(Modifier.fillMaxWidth().clickable {
|
||||||
if(inputFilter.size == allInputs.size) {
|
if(inputFilter.size == allInputs.size) {
|
||||||
inputFilter.clear()
|
inputFilter.clear()
|
||||||
@@ -795,7 +809,7 @@ fun ProjectPlotArea(vm: ProjectVM, benchmark: ProjectVM.Benchmark) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items((allInputs - inputFilter.toSet()).toList()) {
|
items((visibleInputs - inputFilter.toSet()).toList()) {
|
||||||
Row(Modifier.fillMaxWidth().clickable {
|
Row(Modifier.fillMaxWidth().clickable {
|
||||||
if(inputFilter.size == allInputs.size) {
|
if(inputFilter.size == allInputs.size) {
|
||||||
inputFilter.clear()
|
inputFilter.clear()
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ import kotlin.uuid.Uuid
|
|||||||
|
|
||||||
object JVMStore : IStore {
|
object JVMStore : IStore {
|
||||||
private val json = Json
|
private val json = Json
|
||||||
const val SERVICE = "com.jaytux.phoebench"
|
const val SERVICE = PersistenceConstants.SERVICE
|
||||||
|
|
||||||
private class StoredProperty<T>(
|
private class StoredProperty<T>(
|
||||||
val key: String,
|
val key: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user