Micro optimize interner
This commit is contained in:
parent
064689fc25
commit
d0862ab454
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user