Skip to content

Commit 42146e2

Browse files
author
Abduqodiri Qurbonzoda
committed
Add canonicalization benchmarks
1 parent 6b0db5e commit 42146e2

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

benchmarks-mpp/src/jvmMain/kotlin/benchmarks/immutableMap/Remove.kt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import benchmarks.*
2020
import kotlinx.collections.immutable.PersistentMap
2121
import kotlinx.collections.immutable.persistentMapOf
2222
import org.openjdk.jmh.annotations.*
23+
import org.openjdk.jmh.infra.Blackhole
2324

2425
@State(Scope.Thread)
2526
open class Remove {
@@ -34,11 +35,13 @@ open class Remove {
3435

3536
private var keys = listOf<IntWrapper>()
3637
private var persistentMap = persistentMapOf<IntWrapper, String>()
38+
private var halfHeightPersistentMap = persistentMapOf<IntWrapper, String>()
3739

3840
@Setup(Level.Trial)
3941
fun prepare() {
4042
keys = generateKeys(hashCodeType, size)
4143
persistentMap = persistentMapPut(implementation, keys)
44+
halfHeightPersistentMap = halfHeightPersistentMap(persistentMap, keys)
4245

4346
if (hashCodeType == NON_EXISTING_HASH_CODE)
4447
keys = generateKeys(hashCodeType, size)
@@ -52,4 +55,45 @@ open class Remove {
5255
}
5356
return map
5457
}
58+
59+
/**
60+
* Puts `size - entriesForHalfHeight(size)` new entries to a persistent map of size `entriesForHalfHeight(size)`
61+
* that had initially [size] entries.
62+
*
63+
* Measures mean time and memory spent per (roughly one) `put` operation.
64+
*
65+
* Expected time: [Put.put]
66+
* Expected memory: [Put.put]
67+
*/
68+
@Benchmark
69+
fun putAfterRemove(): PersistentMap<IntWrapper, String> {
70+
var map = halfHeightPersistentMap
71+
72+
repeat(size - halfHeightPersistentMap.size) { index ->
73+
map = map.put(keys[index], "some element")
74+
}
75+
76+
return map
77+
}
78+
79+
/**
80+
* Iterates keys of a persistent map of size `entriesForHalfHeight(size)` several times until iterating [size] elements.
81+
*
82+
* Measures mean time and memory spent per `iterate` operation.
83+
*
84+
* Expected time: [Iterate.iterateKeys] with [Iterate.size] = `entriesForHalfHeight([size])`
85+
* Expected memory: [Iterate.iterateKeys] with [Iterate.size] = `entriesForHalfHeight([size])`
86+
*/
87+
@Benchmark
88+
fun iterateKeysAfterRemove(bh: Blackhole) {
89+
var count = 0
90+
while (count < size) {
91+
for (e in halfHeightPersistentMap) {
92+
bh.consume(e)
93+
94+
if (++count == size)
95+
break
96+
}
97+
}
98+
}
5599
}

benchmarks-mpp/src/jvmMain/kotlin/benchmarks/immutableMap/utils.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import benchmarks.*
2020
import kotlinx.collections.immutable.PersistentMap
2121
import kotlinx.collections.immutable.persistentHashMapOf
2222
import kotlinx.collections.immutable.persistentMapOf
23+
import kotlin.math.ceil
24+
import kotlin.math.log
2325

2426

2527
fun <K, V> emptyPersistentMap(implementation: String): PersistentMap<K, V> = when (implementation) {
@@ -35,3 +37,22 @@ fun <K> persistentMapPut(implementation: String, keys: List<K>): PersistentMap<K
3537
}
3638
return map
3739
}
40+
41+
private fun entriesForHalfHeight(size: Int): Int {
42+
val branchingFactor = 32
43+
val logBranchingFactor = 5
44+
45+
val approximateHeight = ceil(log(size.toDouble(), branchingFactor.toDouble())).toInt()
46+
return 1 shl ((approximateHeight / 2) * logBranchingFactor)
47+
}
48+
49+
50+
fun <K> halfHeightPersistentMap(persistentMap: PersistentMap<K, String>, keys: List<K>): PersistentMap<K, String> {
51+
val elementsToLeave = entriesForHalfHeight(persistentMap.size)
52+
53+
var map = persistentMap
54+
repeat(persistentMap.size - elementsToLeave) { index ->
55+
map = map.remove(keys[index])
56+
}
57+
return map
58+
}

benchmarks-mpp/src/jvmMain/kotlin/benchmarks/immutableSet/Remove.kt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import benchmarks.*
2020
import kotlinx.collections.immutable.ImmutableSet
2121
import kotlinx.collections.immutable.persistentSetOf
2222
import org.openjdk.jmh.annotations.*
23+
import org.openjdk.jmh.infra.Blackhole
2324

2425
@State(Scope.Thread)
2526
open class Remove {
@@ -34,11 +35,13 @@ open class Remove {
3435

3536
private var elements = listOf<IntWrapper>()
3637
private var persistentSet = persistentSetOf<IntWrapper>()
38+
private var halfHeightPersistentSet = persistentSetOf<IntWrapper>()
3739

3840
@Setup(Level.Trial)
3941
fun prepare() {
4042
elements = generateElements(hashCodeType, size)
4143
persistentSet = persistentSetAdd(implementation, elements)
44+
halfHeightPersistentSet = halfHeightPersistentSet(persistentSet, elements)
4245

4346
if (hashCodeType == NON_EXISTING_HASH_CODE)
4447
elements = generateElements(hashCodeType, size)
@@ -52,4 +55,45 @@ open class Remove {
5255
}
5356
return set
5457
}
58+
59+
/**
60+
* Adds `size - elementsForHalfHeight(size)` new elements to a persistent set of size `elementsForHalfHeight(size)`
61+
* that had initially [size] elements.
62+
*
63+
* Measures mean time and memory spent per (roughly one) `add` operation.
64+
*
65+
* Expected time: [Add.add]
66+
* Expected memory: [Add.add]
67+
*/
68+
@Benchmark
69+
fun addAfterRemove(): ImmutableSet<IntWrapper> {
70+
var set = halfHeightPersistentSet
71+
72+
repeat(size - halfHeightPersistentSet.size) { index ->
73+
set = set.add(elements[index])
74+
}
75+
76+
return set
77+
}
78+
79+
/**
80+
* Iterates elements of a persistent set of size `elementsForHalfHeight(size)` several times until iterating [size] elements.
81+
*
82+
* Measures mean time and memory spent per `iterate` operation.
83+
*
84+
* Expected time: [Iterate.iterate] with [Iterate.size] = `elementsForHalfHeight([size])`
85+
* Expected memory: [Iterate.iterate] with [Iterate.size] = `elementsForHalfHeight([size])`
86+
*/
87+
@Benchmark
88+
fun iterateAfterRemove(bh: Blackhole) {
89+
var count = 0
90+
while (count < size) {
91+
for (e in halfHeightPersistentSet) {
92+
bh.consume(e)
93+
94+
if (++count == size)
95+
break
96+
}
97+
}
98+
}
5599
}

benchmarks-mpp/src/jvmMain/kotlin/benchmarks/immutableSet/utils.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import benchmarks.*
2020
import kotlinx.collections.immutable.PersistentSet
2121
import kotlinx.collections.immutable.persistentHashSetOf
2222
import kotlinx.collections.immutable.persistentSetOf
23+
import kotlin.math.ceil
24+
import kotlin.math.log
2325

2426

2527
fun <E> emptyPersistentSet(implementation: String): PersistentSet<E> = when (implementation) {
@@ -35,3 +37,21 @@ fun <E> persistentSetAdd(implementation: String, elements: List<E>): PersistentS
3537
}
3638
return set
3739
}
40+
41+
private fun elementsForHalfHeight(size: Int): Int {
42+
val branchingFactor = 32
43+
val logBranchingFactor = 5
44+
45+
val approximateHeight = ceil(log(size.toDouble(), branchingFactor.toDouble())).toInt()
46+
return 1 shl ((approximateHeight / 2) * logBranchingFactor)
47+
}
48+
49+
fun <E> halfHeightPersistentSet(persistentSet: PersistentSet<E>, elements: List<E>): PersistentSet<E> {
50+
val elementsToLeave = elementsForHalfHeight(persistentSet.size)
51+
52+
var set = persistentSet
53+
repeat(persistentSet.size - elementsToLeave) { index ->
54+
set = set.remove(elements[index])
55+
}
56+
return set
57+
}

0 commit comments

Comments
 (0)