Performance improvements

- improvementFilter checks map instead of array for textual match
- forCityGetMatchingUniques does not string-serialize conditionals - revealed by flame chart to be significant
This commit is contained in:
Yair Morgenstern
2023-06-17 23:47:49 +03:00
parent 639d34e28d
commit 259eeeb56c
3 changed files with 13 additions and 14 deletions

View File

@ -29,10 +29,10 @@ class TileStatFunctions(val tile: Tile) {
if (city != null) { if (city != null) {
var tileUniques = var tileUniques =
localUniqueCache.forCityGetMatchingUniques( localUniqueCache.forCityGetMatchingUniques(
city, UniqueType.StatsFromTiles, StateForConditionals.IgnoreConditionals) city, UniqueType.StatsFromTiles, true)
.filter { city.matchesFilter(it.params[2]) } .filter { city.matchesFilter(it.params[2]) }
tileUniques += localUniqueCache.forCityGetMatchingUniques( tileUniques += localUniqueCache.forCityGetMatchingUniques(
city, UniqueType.StatsFromObject, StateForConditionals.IgnoreConditionals) city, UniqueType.StatsFromObject, true)
for (unique in tileUniques) { for (unique in tileUniques) {
if (!unique.conditionalsApply(stateForConditionals)) continue if (!unique.conditionalsApply(stateForConditionals)) continue
val tileType = unique.params[1] val tileType = unique.params[1]
@ -41,7 +41,7 @@ class TileStatFunctions(val tile: Tile) {
} }
for (unique in localUniqueCache.forCityGetMatchingUniques( for (unique in localUniqueCache.forCityGetMatchingUniques(
city, UniqueType.StatsFromTilesWithout, StateForConditionals.IgnoreConditionals)) { city, UniqueType.StatsFromTilesWithout, true)) {
if ( if (
unique.conditionalsApply(stateForConditionals) && unique.conditionalsApply(stateForConditionals) &&
tile.matchesTerrainFilter(unique.params[1]) && tile.matchesTerrainFilter(unique.params[1]) &&
@ -118,7 +118,7 @@ class TileStatFunctions(val tile: Tile) {
if (city != null) { if (city != null) {
// Since the tile changes every time, we cache all uniques, and filter by conditional state only when iterating // Since the tile changes every time, we cache all uniques, and filter by conditional state only when iterating
val cachedStatPercentFromObjectCityUniques = uniqueCache.forCityGetMatchingUniques( val cachedStatPercentFromObjectCityUniques = uniqueCache.forCityGetMatchingUniques(
city, UniqueType.StatPercentFromObject, StateForConditionals.IgnoreConditionals) city, UniqueType.StatPercentFromObject, true)
for (unique in cachedStatPercentFromObjectCityUniques) { for (unique in cachedStatPercentFromObjectCityUniques) {
if (!unique.conditionalsApply(stateForConditionals)) continue if (!unique.conditionalsApply(stateForConditionals)) continue
@ -128,7 +128,7 @@ class TileStatFunctions(val tile: Tile) {
} }
val cachedAllStatPercentFromObjectCityUniques = uniqueCache.forCityGetMatchingUniques( val cachedAllStatPercentFromObjectCityUniques = uniqueCache.forCityGetMatchingUniques(
city, UniqueType.AllStatsPercentFromObject, StateForConditionals.IgnoreConditionals) city, UniqueType.AllStatsPercentFromObject, true)
for (unique in cachedAllStatPercentFromObjectCityUniques) { for (unique in cachedAllStatPercentFromObjectCityUniques) {
if (!unique.conditionalsApply(stateForConditionals)) continue if (!unique.conditionalsApply(stateForConditionals)) continue
val tileFilter = unique.params[1] val tileFilter = unique.params[1]
@ -243,7 +243,7 @@ class TileStatFunctions(val tile: Tile) {
// therefore if we want the cache to be useful it needs to hold the pre-filtered uniques, // therefore if we want the cache to be useful it needs to hold the pre-filtered uniques,
// and then for each improvement we'll filter the uniques locally. // and then for each improvement we'll filter the uniques locally.
// This is still a MASSIVE save of RAM! // This is still a MASSIVE save of RAM!
val tileUniques = uniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromTiles, StateForConditionals.IgnoreConditionals) val tileUniques = uniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromTiles, true)
.filter { city.matchesFilter(it.params[2]) } // These are the uniques for all improvements for this city, .filter { city.matchesFilter(it.params[2]) } // These are the uniques for all improvements for this city,
.filter { it.conditionalsApply(conditionalState) } // ...and this is those with applicable conditions .filter { it.conditionalsApply(conditionalState) } // ...and this is those with applicable conditions
val improvementUniques = val improvementUniques =
@ -264,7 +264,7 @@ class TileStatFunctions(val tile: Tile) {
val uniques = uniqueCache.forCityGetMatchingUniques( val uniques = uniqueCache.forCityGetMatchingUniques(
city, city,
UniqueType.StatsFromObject, UniqueType.StatsFromObject,
StateForConditionals.IgnoreConditionals true
).filter { it.conditionalsApply(conditionalState) } ).filter { it.conditionalsApply(conditionalState) }
for (unique in uniques) { for (unique in uniques) {
if (improvement.matchesFilter(unique.params[1])) { if (improvement.matchesFilter(unique.params[1])) {
@ -296,7 +296,7 @@ class TileStatFunctions(val tile: Tile) {
val allStatPercentUniques = cityUniqueCache.forCityGetMatchingUniques( val allStatPercentUniques = cityUniqueCache.forCityGetMatchingUniques(
city, city,
UniqueType.AllStatsPercentFromObject, UniqueType.AllStatsPercentFromObject,
StateForConditionals.IgnoreConditionals true
).filter { it.conditionalsApply(conditionalState) } ).filter { it.conditionalsApply(conditionalState) }
for (unique in allStatPercentUniques) { for (unique in allStatPercentUniques) {
if (!improvement.matchesFilter(unique.params[1])) continue if (!improvement.matchesFilter(unique.params[1])) continue
@ -309,7 +309,7 @@ class TileStatFunctions(val tile: Tile) {
val statPercentUniques = cityUniqueCache.forCityGetMatchingUniques( val statPercentUniques = cityUniqueCache.forCityGetMatchingUniques(
city, city,
UniqueType.StatPercentFromObject, UniqueType.StatPercentFromObject,
StateForConditionals.IgnoreConditionals true
).filter { it.conditionalsApply(conditionalState) } ).filter { it.conditionalsApply(conditionalState) }
for (unique in statPercentUniques) { for (unique in statPercentUniques) {

View File

@ -126,7 +126,7 @@ class TileImprovement : RulesetStatsObject() {
"All" -> true "All" -> true
"All Road" -> isRoad() "All Road" -> isRoad()
"Great Improvement", "Great" -> isGreatImprovement() "Great Improvement", "Great" -> isGreatImprovement()
in uniques -> true in uniqueMap -> true
else -> false else -> false
} }
} }

View File

@ -311,11 +311,10 @@ class LocalUniqueCache(val cache:Boolean = true) {
fun forCityGetMatchingUniques( fun forCityGetMatchingUniques(
city: City, city: City,
uniqueType: UniqueType, uniqueType: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals( ignoreConditionals: Boolean = false
city.civ,
city
)
): Sequence<Unique> { ): Sequence<Unique> {
val stateForConditionals = if (ignoreConditionals) StateForConditionals.IgnoreConditionals
else StateForConditionals(city.civ, city)
return get( return get(
"city-${city.id}-${uniqueType.name}-${stateForConditionals}", "city-${city.id}-${uniqueType.name}-${stateForConditionals}",
city.getMatchingUniques(uniqueType, stateForConditionals) city.getMatchingUniques(uniqueType, stateForConditionals)