Resolved #9745 - memory improvement, cache uniquemap for tiles with identical terrain

This commit is contained in:
Yair Morgenstern
2023-07-09 10:12:16 +03:00
parent d9b1d22949
commit 31f6a406c2
2 changed files with 21 additions and 4 deletions

View File

@ -12,8 +12,10 @@ import com.unciv.models.metadata.Player
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.nation.Nation import com.unciv.models.ruleset.nation.Nation
import com.unciv.models.ruleset.tile.TerrainType import com.unciv.models.ruleset.tile.TerrainType
import com.unciv.models.ruleset.unique.UniqueMap
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import java.lang.Integer.max import java.lang.Integer.max
import java.util.concurrent.ConcurrentHashMap
import kotlin.math.abs import kotlin.math.abs
/** An Unciv map with all properties as produced by the [map editor][com.unciv.ui.screens.mapeditorscreen.MapEditorScreen] /** An Unciv map with all properties as produced by the [map editor][com.unciv.ui.screens.mapeditorscreen.MapEditorScreen]
@ -60,6 +62,9 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
@Transient @Transient
var ruleset: Ruleset? = null var ruleset: Ruleset? = null
@Transient
var tileUniqueMapCache = ConcurrentHashMap<String, UniqueMap>()
@Transient @Transient
var tileMatrix = ArrayList<ArrayList<Tile?>>() // this works several times faster than a hashmap, the performance difference is really astounding var tileMatrix = ArrayList<ArrayList<Tile?>>() // this works several times faster than a hashmap, the performance difference is really astounding
@ -140,6 +145,7 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
toReturn.startingLocations.clear() toReturn.startingLocations.clear()
toReturn.startingLocations.ensureCapacity(startingLocations.size) toReturn.startingLocations.ensureCapacity(startingLocations.size)
toReturn.startingLocations.addAll(startingLocations) toReturn.startingLocations.addAll(startingLocations)
toReturn.tileUniqueMapCache = tileUniqueMapCache
return toReturn return toReturn
} }

View File

@ -832,9 +832,7 @@ open class Tile : IsPartOfGameInfoSerialization {
yieldAll(terrainFeatureObjects) yieldAll(terrainFeatureObjects)
}.toList().asSequence() //Save in memory, and return as sequence }.toList().asSequence() //Save in memory, and return as sequence
val newUniqueMap = UniqueMap() updateUniqueMap()
for (terrain in allTerrains)
newUniqueMap.addUniques(terrain.uniqueObjects)
lastTerrain = when { lastTerrain = when {
terrainFeatures.isNotEmpty() -> ruleset.terrains[terrainFeatures.last()] terrainFeatures.isNotEmpty() -> ruleset.terrains[terrainFeatures.last()]
@ -842,7 +840,20 @@ open class Tile : IsPartOfGameInfoSerialization {
naturalWonder != null -> getNaturalWonder() naturalWonder != null -> getNaturalWonder()
else -> getBaseTerrain() else -> getBaseTerrain()
} }
terrainUniqueMap = newUniqueMap }
private fun updateUniqueMap() {
if (!::tileMap.isInitialized) return // This tile is a fake tile, for visual display only (e.g. map editor, civilopedia)
val terrainString = allTerrains.joinToString(";") { it.name }
val cachedUniqueMap = tileMap.tileUniqueMapCache[terrainString]
terrainUniqueMap = if (cachedUniqueMap != null) cachedUniqueMap
else {
val newUniqueMap = UniqueMap()
for (terrain in allTerrains)
newUniqueMap.addUniques(terrain.uniqueObjects)
tileMap.tileUniqueMapCache[terrainString] = newUniqueMap
newUniqueMap
}
} }
fun addTerrainFeature(terrainFeature: String) = fun addTerrainFeature(terrainFeature: String) =