From d7b277b6b55db03e0ab0529b17f9d15c4078ba25 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Tue, 18 Jul 2023 18:28:04 +0300 Subject: [PATCH] Memory performance improvement - don't create strings when you can instead hash the list! New ists are cheaper in-memory than new strings (only need to allocate "number of strings in list" pointers, and not "number of chars in all strings" chars) --- core/src/com/unciv/logic/map/TileMap.kt | 2 +- core/src/com/unciv/logic/map/tile/Tile.kt | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/com/unciv/logic/map/TileMap.kt b/core/src/com/unciv/logic/map/TileMap.kt index 43ce3c1bcc..2d27816ad6 100644 --- a/core/src/com/unciv/logic/map/TileMap.kt +++ b/core/src/com/unciv/logic/map/TileMap.kt @@ -63,7 +63,7 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization { var ruleset: Ruleset? = null @Transient - var tileUniqueMapCache = ConcurrentHashMap() + var tileUniqueMapCache = ConcurrentHashMap, UniqueMap>() @Transient var tileMatrix = ArrayList>() // this works several times faster than a hashmap, the performance difference is really astounding diff --git a/core/src/com/unciv/logic/map/tile/Tile.kt b/core/src/com/unciv/logic/map/tile/Tile.kt index d0a5ae617a..0a266e3bfd 100644 --- a/core/src/com/unciv/logic/map/tile/Tile.kt +++ b/core/src/com/unciv/logic/map/tile/Tile.kt @@ -844,14 +844,17 @@ open class Tile : IsPartOfGameInfoSerialization { 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 + 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 + val cachedUniqueMap = tileMap.tileUniqueMapCache[terrainNameList] + terrainUniqueMap = if (cachedUniqueMap != null) + cachedUniqueMap else { val newUniqueMap = UniqueMap() for (terrain in allTerrains) newUniqueMap.addUniques(terrain.uniqueObjects) - tileMap.tileUniqueMapCache[terrainString] = newUniqueMap + tileMap.tileUniqueMapCache[terrainNameList] = newUniqueMap newUniqueMap } }