perf: save more metadata per "list of terrains" for fast lookups, this time for edge tiles

This commit is contained in:
yairm210 2024-12-15 19:53:01 +02:00
parent 7bc5047ace
commit 1a0bb512bf
3 changed files with 17 additions and 7 deletions

View File

@ -75,8 +75,17 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
@Transient
var ruleset: Ruleset? = null
data class TerrainListData(
val uniques: UniqueMap,
val terrainNameSet: Set<String>
){
companion object{
val EMPTY = TerrainListData(UniqueMap.EMPTY, emptySet())
}
}
@Transient
var tileUniqueMapCache = ConcurrentHashMap<List<String>, UniqueMap>()
var tileUniqueMapCache = ConcurrentHashMap<List<String>, TerrainListData>()
@Transient
var tileMatrix = ArrayList<ArrayList<Tile?>>() // this works several times faster than a hashmap, the performance difference is really astounding

View File

@ -156,7 +156,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
private set
@Transient
var terrainUniqueMap = UniqueMap.EMPTY
var cachedTerrainData = TileMap.TerrainListData.EMPTY
private set
@Transient
@ -373,10 +373,10 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
internal var stateThisTile: StateForConditionals = StateForConditionals.EmptyState
/** Checks whether any of the TERRAINS of this tile has a certain unique */
fun terrainHasUnique(uniqueType: UniqueType, state: StateForConditionals = stateThisTile) =
terrainUniqueMap.getMatchingUniques(uniqueType, state).any()
cachedTerrainData.uniques.hasMatchingUnique(uniqueType, state)
/** Get all uniques of this type that any TERRAIN on this tile has */
fun getTerrainMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = stateThisTile ): Sequence<Unique> {
return terrainUniqueMap.getMatchingUniques(uniqueType, stateForConditionals)
return cachedTerrainData.uniques.getMatchingUniques(uniqueType, stateForConditionals)
}
/** Get all uniques of this type that any part of this tile has: terrains, improvement, resource */
@ -835,8 +835,9 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
val terrainNameList = allTerrains.map { it.name }.toList()
// List hash is function of all its items, so the same items in the same order will always give the same hash
terrainUniqueMap = tileMap.tileUniqueMapCache.getOrPut(terrainNameList) {
UniqueMap(allTerrains.flatMap { it.uniqueObjects })
cachedTerrainData = tileMap.tileUniqueMapCache.getOrPut(terrainNameList) {
TileMap.TerrainListData(UniqueMap(allTerrains.flatMap { it.uniqueObjects }),
terrainNameList.toSet())
}
}

View File

@ -109,7 +109,7 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
// Required for performance - full matchesFilter is too expensive for something that needs to run every update()
fun matchesFilterMinimal(originTile: Tile, filter: String): Boolean {
if (originTile.allTerrains.any { it.name == filter }) return true
if (originTile.cachedTerrainData.terrainNameSet.contains(filter)) return true
if (originTile.getBaseTerrain().type.name == filter) return true
return false
}