Greatly improve performance of clusterization by hinting that min/max should be performed with implied zero value
This commit is contained in:
parent
b1783343bc
commit
acc182eb26
@ -104,7 +104,7 @@ class EnergyCounterRenderer(private val context: BlockEntityRendererProvider.Con
|
|||||||
|
|
||||||
map[1f] = maximum.formatPower()
|
map[1f] = maximum.formatPower()
|
||||||
|
|
||||||
for (cluster in chart.asIterable().clusterize(random)) {
|
for (cluster in chart.asIterable().clusterize(random, zeroBound = true)) {
|
||||||
val perc = (cluster.center / maximum).toFloat()
|
val perc = (cluster.center / maximum).toFloat()
|
||||||
|
|
||||||
if (map.keys.none { (it - perc).absoluteValue < 0.08f }) {
|
if (map.keys.none { (it - perc).absoluteValue < 0.08f }) {
|
||||||
|
@ -90,6 +90,7 @@ private class MutableCluster<V : Comparable<V>>(var center: V) {
|
|||||||
private fun <V : Comparable<V>> Iterable<V>.clusterize(
|
private fun <V : Comparable<V>> Iterable<V>.clusterize(
|
||||||
random: RandomGenerator,
|
random: RandomGenerator,
|
||||||
initialClusters: Int = 1,
|
initialClusters: Int = 1,
|
||||||
|
zeroBound: Boolean = false,
|
||||||
identity: V,
|
identity: V,
|
||||||
plus: (V, V) -> V,
|
plus: (V, V) -> V,
|
||||||
minus: (V, V) -> V,
|
minus: (V, V) -> V,
|
||||||
@ -126,8 +127,27 @@ private fun <V : Comparable<V>> Iterable<V>.clusterize(
|
|||||||
cluster.values.add(wrapped)
|
cluster.values.add(wrapped)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zeroBound) {
|
||||||
|
min = minOf(min, identity)
|
||||||
|
max = maxOf(max, identity)
|
||||||
|
}
|
||||||
|
|
||||||
if (min == max) {
|
if (min == max) {
|
||||||
return listOf(Cluster.Impl(listOf(min), min))
|
return listOf(Cluster.Impl(listOf(min), min))
|
||||||
|
} else {
|
||||||
|
// if "clusters" already satisfy constraints...
|
||||||
|
clusters.forEach { it.calculateCenter(identity, plus, minus, divInt, abs) }
|
||||||
|
values.forEach { it.updateError(abs, minus) }
|
||||||
|
|
||||||
|
val maxError = values.maxOf { it.error }
|
||||||
|
|
||||||
|
if (!heuristics(min, max, maxError)) {
|
||||||
|
return clusters.stream()
|
||||||
|
.filter { it.values.isNotEmpty() }
|
||||||
|
.map { Cluster.Impl(it.values.map { it.value }, it.center) }
|
||||||
|
.sorted { o1, o2 -> o2.values.size.compareTo(o1.values.size) } // большие кластеры должны идти первыми
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -182,8 +202,8 @@ private fun <V : Comparable<V>> Iterable<V>.clusterize(
|
|||||||
// TODO: could use some tweaking
|
// TODO: could use some tweaking
|
||||||
private val DECIMAL_ERROR_TOLERANCE = Decimal("0.02")
|
private val DECIMAL_ERROR_TOLERANCE = Decimal("0.02")
|
||||||
|
|
||||||
fun Iterable<Decimal>.clusterize(random: RandomGenerator, clusters: Int? = null): List<Cluster<Decimal>> {
|
fun Iterable<Decimal>.clusterize(random: RandomGenerator, clusters: Int? = null, zeroBound: Boolean = false): List<Cluster<Decimal>> {
|
||||||
return clusterize(random, clusters ?: 1, Decimal.ZERO, Decimal::plus, Decimal::minus, Decimal::div, Decimal::absoluteValue) { min, max, error ->
|
return clusterize(random, clusters ?: 1, zeroBound, Decimal.ZERO, Decimal::plus, Decimal::minus, Decimal::div, Decimal::absoluteValue) { min, max, error ->
|
||||||
if (clusters != null)
|
if (clusters != null)
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
|
@ -456,7 +456,7 @@ private fun formatHistoryChart(
|
|||||||
val rand = java.util.Random()
|
val rand = java.util.Random()
|
||||||
|
|
||||||
if (maxTransferred.isNotZero && transferredMult > 0.2f) {
|
if (maxTransferred.isNotZero && transferredMult > 0.2f) {
|
||||||
for (cluster in widget.transferred.clusterize(rand)) {
|
for (cluster in widget.transferred.clusterize(rand, zeroBound = true)) {
|
||||||
val perc = (cluster.center / maxTransferred).toFloat() * transferredMult
|
val perc = (cluster.center / maxTransferred).toFloat() * transferredMult
|
||||||
|
|
||||||
if (labelNames.keys.none { (it - perc).absoluteValue < 0.08f })
|
if (labelNames.keys.none { (it - perc).absoluteValue < 0.08f })
|
||||||
@ -465,7 +465,7 @@ private fun formatHistoryChart(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (maxReceived.isNotZero && receivedMult > 0.2f) {
|
if (maxReceived.isNotZero && receivedMult > 0.2f) {
|
||||||
for (cluster in widget.received.clusterize(rand)) {
|
for (cluster in widget.received.clusterize(rand, zeroBound = true)) {
|
||||||
val perc = zero + (cluster.center / maxReceived).toFloat() * receivedMult
|
val perc = zero + (cluster.center / maxReceived).toFloat() * receivedMult
|
||||||
|
|
||||||
if (labelNames.keys.none { (it - perc).absoluteValue < 0.08f })
|
if (labelNames.keys.none { (it - perc).absoluteValue < 0.08f })
|
||||||
@ -473,7 +473,7 @@ private fun formatHistoryChart(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val clusters = diff.asIterable().clusterize(rand)
|
val clusters = diff.asIterable().clusterize(rand, zeroBound = true)
|
||||||
|
|
||||||
for (cluster in clusters) {
|
for (cluster in clusters) {
|
||||||
val perc: Float
|
val perc: Float
|
||||||
|
Loading…
Reference in New Issue
Block a user