Skip to content

Commit 5b44313

Browse files
author
Abduqodiri Qurbonzoda
committed
Add canonicalization benchmarks
1 parent 44f49db commit 5b44313

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
@@ -9,6 +9,7 @@ import benchmarks.*
99
import kotlinx.collections.immutable.PersistentMap
1010
import kotlinx.collections.immutable.persistentMapOf
1111
import org.openjdk.jmh.annotations.*
12+
import org.openjdk.jmh.infra.Blackhole
1213

1314
@State(Scope.Thread)
1415
open class Remove {
@@ -23,11 +24,13 @@ open class Remove {
2324

2425
private var keys = listOf<IntWrapper>()
2526
private var persistentMap = persistentMapOf<IntWrapper, String>()
27+
private var halfHeightPersistentMap = persistentMapOf<IntWrapper, String>()
2628

2729
@Setup(Level.Trial)
2830
fun prepare() {
2931
keys = generateKeys(hashCodeType, size)
3032
persistentMap = persistentMapPut(implementation, keys)
33+
halfHeightPersistentMap = halfHeightPersistentMap(persistentMap, keys)
3134

3235
if (hashCodeType == NON_EXISTING_HASH_CODE)
3336
keys = generateKeys(hashCodeType, size)
@@ -41,4 +44,45 @@ open class Remove {
4144
}
4245
return map
4346
}
47+
48+
/**
49+
* Puts `size - entriesForHalfHeight(size)` new entries to a persistent map of size `entriesForHalfHeight(size)`
50+
* that had initially [size] entries.
51+
*
52+
* Measures mean time and memory spent per (roughly one) `put` operation.
53+
*
54+
* Expected time: [Put.put]
55+
* Expected memory: [Put.put]
56+
*/
57+
@Benchmark
58+
fun putAfterRemove(): PersistentMap<IntWrapper, String> {
59+
var map = halfHeightPersistentMap
60+
61+
repeat(size - halfHeightPersistentMap.size) { index ->
62+
map = map.put(keys[index], "some element")
63+
}
64+
65+
return map
66+
}
67+
68+
/**
69+
* Iterates keys of a persistent map of size `entriesForHalfHeight(size)` several times until iterating [size] elements.
70+
*
71+
* Measures mean time and memory spent per `iterate` operation.
72+
*
73+
* Expected time: [Iterate.iterateKeys] with [Iterate.size] = `entriesForHalfHeight([size])`
74+
* Expected memory: [Iterate.iterateKeys] with [Iterate.size] = `entriesForHalfHeight([size])`
75+
*/
76+
@Benchmark
77+
fun iterateKeysAfterRemove(bh: Blackhole) {
78+
var count = 0
79+
while (count < size) {
80+
for (e in halfHeightPersistentMap) {
81+
bh.consume(e)
82+
83+
if (++count == size)
84+
break
85+
}
86+
}
87+
}
4488
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import benchmarks.*
99
import kotlinx.collections.immutable.PersistentMap
1010
import kotlinx.collections.immutable.persistentHashMapOf
1111
import kotlinx.collections.immutable.persistentMapOf
12+
import kotlin.math.ceil
13+
import kotlin.math.log
1214

1315

1416
fun <K, V> emptyPersistentMap(implementation: String): PersistentMap<K, V> = when (implementation) {
@@ -24,3 +26,22 @@ fun <K> persistentMapPut(implementation: String, keys: List<K>): PersistentMap<K
2426
}
2527
return map
2628
}
29+
30+
private fun entriesForHalfHeight(size: Int): Int {
31+
val branchingFactor = 32
32+
val logBranchingFactor = 5
33+
34+
val approximateHeight = ceil(log(size.toDouble(), branchingFactor.toDouble())).toInt()
35+
return 1 shl ((approximateHeight / 2) * logBranchingFactor)
36+
}
37+
38+
39+
fun <K> halfHeightPersistentMap(persistentMap: PersistentMap<K, String>, keys: List<K>): PersistentMap<K, String> {
40+
val elementsToLeave = entriesForHalfHeight(persistentMap.size)
41+
42+
var map = persistentMap
43+
repeat(persistentMap.size - elementsToLeave) { index ->
44+
map = map.remove(keys[index])
45+
}
46+
return map
47+
}

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import benchmarks.*
99
import kotlinx.collections.immutable.ImmutableSet
1010
import kotlinx.collections.immutable.persistentSetOf
1111
import org.openjdk.jmh.annotations.*
12+
import org.openjdk.jmh.infra.Blackhole
1213

1314
@State(Scope.Thread)
1415
open class Remove {
@@ -23,11 +24,13 @@ open class Remove {
2324

2425
private var elements = listOf<IntWrapper>()
2526
private var persistentSet = persistentSetOf<IntWrapper>()
27+
private var halfHeightPersistentSet = persistentSetOf<IntWrapper>()
2628

2729
@Setup(Level.Trial)
2830
fun prepare() {
2931
elements = generateElements(hashCodeType, size)
3032
persistentSet = persistentSetAdd(implementation, elements)
33+
halfHeightPersistentSet = halfHeightPersistentSet(persistentSet, elements)
3134

3235
if (hashCodeType == NON_EXISTING_HASH_CODE)
3336
elements = generateElements(hashCodeType, size)
@@ -41,4 +44,45 @@ open class Remove {
4144
}
4245
return set
4346
}
47+
48+
/**
49+
* Adds `size - elementsForHalfHeight(size)` new elements to a persistent set of size `elementsForHalfHeight(size)`
50+
* that had initially [size] elements.
51+
*
52+
* Measures mean time and memory spent per (roughly one) `add` operation.
53+
*
54+
* Expected time: [Add.add]
55+
* Expected memory: [Add.add]
56+
*/
57+
@Benchmark
58+
fun addAfterRemove(): ImmutableSet<IntWrapper> {
59+
var set = halfHeightPersistentSet
60+
61+
repeat(size - halfHeightPersistentSet.size) { index ->
62+
set = set.add(elements[index])
63+
}
64+
65+
return set
66+
}
67+
68+
/**
69+
* Iterates elements of a persistent set of size `elementsForHalfHeight(size)` several times until iterating [size] elements.
70+
*
71+
* Measures mean time and memory spent per `iterate` operation.
72+
*
73+
* Expected time: [Iterate.iterate] with [Iterate.size] = `elementsForHalfHeight([size])`
74+
* Expected memory: [Iterate.iterate] with [Iterate.size] = `elementsForHalfHeight([size])`
75+
*/
76+
@Benchmark
77+
fun iterateAfterRemove(bh: Blackhole) {
78+
var count = 0
79+
while (count < size) {
80+
for (e in halfHeightPersistentSet) {
81+
bh.consume(e)
82+
83+
if (++count == size)
84+
break
85+
}
86+
}
87+
}
4488
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import benchmarks.*
99
import kotlinx.collections.immutable.PersistentSet
1010
import kotlinx.collections.immutable.persistentHashSetOf
1111
import kotlinx.collections.immutable.persistentSetOf
12+
import kotlin.math.ceil
13+
import kotlin.math.log
1214

1315

1416
fun <E> emptyPersistentSet(implementation: String): PersistentSet<E> = when (implementation) {
@@ -24,3 +26,21 @@ fun <E> persistentSetAdd(implementation: String, elements: List<E>): PersistentS
2426
}
2527
return set
2628
}
29+
30+
private fun elementsForHalfHeight(size: Int): Int {
31+
val branchingFactor = 32
32+
val logBranchingFactor = 5
33+
34+
val approximateHeight = ceil(log(size.toDouble(), branchingFactor.toDouble())).toInt()
35+
return 1 shl ((approximateHeight / 2) * logBranchingFactor)
36+
}
37+
38+
fun <E> halfHeightPersistentSet(persistentSet: PersistentSet<E>, elements: List<E>): PersistentSet<E> {
39+
val elementsToLeave = elementsForHalfHeight(persistentSet.size)
40+
41+
var set = persistentSet
42+
repeat(persistentSet.size - elementsToLeave) { index ->
43+
set = set.remove(elements[index])
44+
}
45+
return set
46+
}

0 commit comments

Comments
 (0)