Micro optimize interner

This commit is contained in:
DBotThePony 2023-10-22 13:39:46 +07:00
parent 064689fc25
commit d0862ab454
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 19 additions and 10 deletions

View File

@ -613,7 +613,7 @@ class StarboundClient : Closeable {
} }
val tileRenderers = TileRenderers(this) val tileRenderers = TileRenderers(this)
var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(16000, 8000), true) var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(3000, 2000), true)
init { init {
clearColor = RGBAColor.SLATE_GRAY clearColor = RGBAColor.SLATE_GRAY

View File

@ -147,9 +147,10 @@ class HashTableInterner<T : Any>(private val segmentBits: Int = log(Runtime.getR
val mask = size - 1 val mask = size - 1
val mem = arrayOfNulls<Ref<T>>(size) val mem = arrayOfNulls<Ref<T>>(size)
var stored = 0 var stored = 0
var collisions = 0
private fun hash(e: Any): Int { private fun hash(e: Any): Int {
return HashCommon.mix(e.hashCode().rotateRight(segmentBits)) and mask return HashCommon.mix(e.hashCode()).rotateRight(segmentBits) and mask
} }
fun remove(ref: Ref<T>): Boolean { fun remove(ref: Ref<T>): Boolean {
@ -161,11 +162,15 @@ class HashTableInterner<T : Any>(private val segmentBits: Int = log(Runtime.getR
return false return false
} else if (search === ref) { } else if (search === ref) {
mem[hash] = search.nextEntry mem[hash] = search.nextEntry
if (mem[hash] != null) check(--collisions >= 0) { "Collision count turned negative" }
check(--stored >= 0) { "Stored count turned negative" } check(--stored >= 0) { "Stored count turned negative" }
return true return true
} else { } else {
return search.remove(ref).also { return search.remove(ref).also {
if (it) check(--stored >= 0) { "Stored count turned negative" } if (it) {
check(--stored >= 0) { "Stored count turned negative" }
check(--collisions >= 0) { "Collision count turned negative" }
}
} }
} }
} }
@ -179,8 +184,10 @@ class HashTableInterner<T : Any>(private val segmentBits: Int = log(Runtime.getR
if (existing == null) if (existing == null)
mem[hash] = ref mem[hash] = ref
else else {
existing.insert(ref) existing.insert(ref)
collisions++
}
} }
fun cleanup(): Int { fun cleanup(): Int {
@ -212,10 +219,9 @@ class HashTableInterner<T : Any>(private val segmentBits: Int = log(Runtime.getR
return new return new
} }
fun search(sample: T): T? { fun search(sample: T, hash: Int): T? {
val mem = mem val mem = mem
val hash = hash(sample) var search = mem[hash and mask]
var search = mem[hash]
while (search != null) { while (search != null) {
val get = search.get() val get = search.get()
@ -231,17 +237,18 @@ class HashTableInterner<T : Any>(private val segmentBits: Int = log(Runtime.getR
} }
override fun intern(sample: T): T { override fun intern(sample: T): T {
val hash = HashCommon.mix(sample.hashCode()) var hash = HashCommon.mix(sample.hashCode())
val segmentIndex = hash and actualSegmentBits val segmentIndex = hash and actualSegmentBits
var segment = segments[segmentIndex] var segment = segments[segmentIndex]
val find = segment.search(sample) hash = hash.rotateRight(segmentBits)
val find = segment.search(sample, hash)
if (find != null) return find if (find != null) return find
locks[segmentIndex].withLock { locks[segmentIndex].withLock {
segment = segments[segmentIndex] segment = segments[segmentIndex]
val find = segment.search(sample) val find = segment.search(sample, hash)
if (find != null) return find if (find != null) return find
if (segment.stored >= segment.mem.size * 0.75f) { if (segment.stored >= segment.mem.size * 0.75f) {

View File

@ -23,6 +23,8 @@ object InternerTest {
val s1 = "String$v" val s1 = "String$v"
val s2 = "String$v" val s2 = "String$v"
check(s1 !== s2)
if (interner.intern(s1) !== interner.intern(s2)) { if (interner.intern(s1) !== interner.intern(s2)) {
misses.incrementAndGet() misses.incrementAndGet()
} }