Skip to content

Commit bad089a

Browse files
Optimised LRU cache.
Signed-off-by: Kenneth J. Shackleton <kshackleton1@bloomberg.net>
1 parent 2fbda51 commit bad089a

File tree

15 files changed

+1200
-51
lines changed

15 files changed

+1200
-51
lines changed

selekt-java/src/jmh/kotlin/com/bloomberg/selekt/cache/benchmarks/LruCacheBenchmark.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ open class LruCacheBenchmark {
3939
@Benchmark
4040
@BenchmarkMode(Mode.Throughput)
4141
fun getEntry(input: CacheInput) = input.cache.run {
42-
this["1", {}]
42+
get("1") {}
4343
}
4444

4545
@Benchmark
4646
@BenchmarkMode(Mode.Throughput)
4747
fun getEntryWithEviction(input: CacheInput) = input.cache.run {
48-
this["1", {}]
49-
this["2", {}]
48+
get("1") {}
49+
get("2") {}
5050
}
5151
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2024 Bloomberg Finance L.P.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bloomberg.selekt.collections.map.benchmarks
18+
19+
import com.bloomberg.selekt.collections.map.FastLinkedStringMap
20+
import org.openjdk.jmh.annotations.Benchmark
21+
import org.openjdk.jmh.annotations.BenchmarkMode
22+
import org.openjdk.jmh.annotations.Level
23+
import org.openjdk.jmh.annotations.Mode
24+
import org.openjdk.jmh.annotations.Scope
25+
import org.openjdk.jmh.annotations.Setup
26+
import org.openjdk.jmh.annotations.State
27+
28+
@State(Scope.Thread)
29+
open class LinkedMapInput {
30+
internal lateinit var smallMap: FastLinkedStringMap<Any>
31+
internal lateinit var largeMap: FastLinkedStringMap<Any>
32+
internal lateinit var largeAccessMap: FastLinkedStringMap<Any>
33+
34+
@Setup(Level.Iteration)
35+
fun setUp() {
36+
smallMap = FastLinkedStringMap(1, 1) {}
37+
largeMap = FastLinkedStringMap(64, 64, false) {}
38+
largeAccessMap = FastLinkedStringMap(64, 64, true) {}
39+
}
40+
}
41+
42+
open class FastLinkedStringMapBenchmark {
43+
@Benchmark
44+
@BenchmarkMode(Mode.Throughput)
45+
fun getEntry(input: LinkedMapInput) = input.smallMap.run {
46+
getElsePut("1") { "" }
47+
}
48+
49+
@Benchmark
50+
@BenchmarkMode(Mode.Throughput)
51+
fun getEntries(input: LinkedMapInput) = input.largeMap.run {
52+
getElsePut("1") { "" }
53+
getElsePut("2") { "" }
54+
}
55+
56+
@Benchmark
57+
@BenchmarkMode(Mode.Throughput)
58+
fun getEntriesDifferentLengths(input: LinkedMapInput) = input.largeMap.run {
59+
getElsePut("1") { "" }
60+
getElsePut("23") { "" }
61+
}
62+
63+
@Benchmark
64+
@BenchmarkMode(Mode.Throughput)
65+
fun getEntriesAccessOrder(input: LinkedMapInput) = input.largeAccessMap.run {
66+
getElsePut("1") { "" }
67+
getElsePut("2") { "" }
68+
}
69+
70+
@Benchmark
71+
@BenchmarkMode(Mode.Throughput)
72+
fun getEntriesWithCollision(input: LinkedMapInput) = input.smallMap.run {
73+
getElsePut("1") { "" }
74+
getElsePut("2") { "" }
75+
}
76+
77+
@Benchmark
78+
@BenchmarkMode(Mode.Throughput)
79+
fun getEntriesDifferentLengthsWithCollision(input: LinkedMapInput) = input.smallMap.run {
80+
getElsePut("1") { "" }
81+
getElsePut("23") { "" }
82+
}
83+
84+
@Benchmark
85+
@BenchmarkMode(Mode.Throughput)
86+
fun getThenRemoveEntry(input: LinkedMapInput) = input.smallMap.run {
87+
getElsePut("1") { "" }
88+
removeEntry("1")
89+
}
90+
91+
@Benchmark
92+
@BenchmarkMode(Mode.Throughput)
93+
fun getThenRemoveKey(input: LinkedMapInput) = input.smallMap.run {
94+
getElsePut("1") { "" }
95+
removeKey("1")
96+
}
97+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2024 Bloomberg Finance L.P.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bloomberg.selekt.collections.map.benchmarks
18+
19+
import com.bloomberg.selekt.collections.map.FastStringMap
20+
import org.openjdk.jmh.annotations.Benchmark
21+
import org.openjdk.jmh.annotations.BenchmarkMode
22+
import org.openjdk.jmh.annotations.Level
23+
import org.openjdk.jmh.annotations.Mode
24+
import org.openjdk.jmh.annotations.Scope
25+
import org.openjdk.jmh.annotations.Setup
26+
import org.openjdk.jmh.annotations.State
27+
28+
@State(Scope.Thread)
29+
open class MapInput {
30+
internal lateinit var map: FastStringMap<Any>
31+
32+
@Setup(Level.Iteration)
33+
fun setUp() {
34+
map = FastStringMap(1)
35+
}
36+
}
37+
38+
open class FastStringMapBenchmark {
39+
@Benchmark
40+
@BenchmarkMode(Mode.Throughput)
41+
fun getEntry(input: MapInput) = input.map.run {
42+
getEntryElsePut("1") { "" }
43+
}
44+
45+
@Benchmark
46+
@BenchmarkMode(Mode.Throughput)
47+
fun getEntryWithCollision(input: MapInput) = input.map.run {
48+
getEntryElsePut("1") { "" }
49+
getEntryElsePut("2") { "" }
50+
}
51+
52+
@Benchmark
53+
@BenchmarkMode(Mode.Throughput)
54+
fun getThenRemoveEntry(input: MapInput) = input.map.run {
55+
getEntryElsePut("1") { "" }
56+
removeEntry("1")
57+
}
58+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2024 Bloomberg Finance L.P.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bloomberg.selekt.jdk
18+
19+
import org.openjdk.jmh.annotations.Benchmark
20+
import org.openjdk.jmh.annotations.BenchmarkMode
21+
import org.openjdk.jmh.annotations.Level
22+
import org.openjdk.jmh.annotations.Mode
23+
import org.openjdk.jmh.annotations.Scope
24+
import org.openjdk.jmh.annotations.Setup
25+
import org.openjdk.jmh.annotations.State
26+
27+
@State(Scope.Thread)
28+
open class ArrayInput {
29+
internal lateinit var array: Array<Any>
30+
31+
@Setup(Level.Iteration)
32+
fun setUp() {
33+
array = Array(2) { Any() }
34+
}
35+
}
36+
37+
open class ArrayBenchmark {
38+
@Benchmark
39+
@BenchmarkMode(Mode.Throughput)
40+
fun getFirst(input: ArrayInput) = input.array.run {
41+
firstOrNull()
42+
}
43+
44+
@Benchmark
45+
@BenchmarkMode(Mode.Throughput)
46+
fun getEntries(input: ArrayInput) = input.array.run {
47+
firstOrNull()
48+
this[1]
49+
}
50+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2024 Bloomberg Finance L.P.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bloomberg.selekt.jdk
18+
19+
import org.openjdk.jmh.annotations.Benchmark
20+
import org.openjdk.jmh.annotations.BenchmarkMode
21+
import org.openjdk.jmh.annotations.Level
22+
import org.openjdk.jmh.annotations.Mode
23+
import org.openjdk.jmh.annotations.Scope
24+
import org.openjdk.jmh.annotations.Setup
25+
import org.openjdk.jmh.annotations.State
26+
27+
@State(Scope.Thread)
28+
open class ArrayListInput {
29+
internal lateinit var list: ArrayList<Any>
30+
31+
@Setup(Level.Iteration)
32+
fun setUp() {
33+
list = ArrayList<Any>(1).apply {
34+
add(Any())
35+
add(Any())
36+
}
37+
}
38+
}
39+
40+
open class ArrayListBenchmark {
41+
@Benchmark
42+
@BenchmarkMode(Mode.Throughput)
43+
fun getFirst(input: ArrayListInput) = input.list.run {
44+
firstOrNull()
45+
}
46+
47+
@Benchmark
48+
@BenchmarkMode(Mode.Throughput)
49+
fun getEntries(input: ArrayListInput) = input.list.run {
50+
firstOrNull()
51+
this[1]
52+
}
53+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2024 Bloomberg Finance L.P.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bloomberg.selekt.jdk
18+
19+
import org.openjdk.jmh.annotations.Benchmark
20+
import org.openjdk.jmh.annotations.BenchmarkMode
21+
import org.openjdk.jmh.annotations.Level
22+
import org.openjdk.jmh.annotations.Mode
23+
import org.openjdk.jmh.annotations.Scope
24+
import org.openjdk.jmh.annotations.Setup
25+
import org.openjdk.jmh.annotations.State
26+
27+
@State(Scope.Thread)
28+
open class HashMapInput {
29+
internal lateinit var smallMap: HashMap<String, Any>
30+
internal lateinit var largeMap: HashMap<String, Any>
31+
32+
@Setup(Level.Iteration)
33+
fun setUp() {
34+
smallMap = HashMap(1)
35+
largeMap = HashMap(64)
36+
}
37+
}
38+
39+
open class FastStringMapBenchmark {
40+
@Benchmark
41+
@BenchmarkMode(Mode.Throughput)
42+
fun getEntry(input: HashMapInput) = input.smallMap.run {
43+
getOrPut("1") { "" }
44+
}
45+
46+
@Benchmark
47+
@BenchmarkMode(Mode.Throughput)
48+
fun getEntries(input: HashMapInput) = input.largeMap.run {
49+
getOrPut("1") { "" }
50+
getOrPut("2") { "" }
51+
}
52+
53+
@Benchmark
54+
@BenchmarkMode(Mode.Throughput)
55+
fun getEntryWithCollision(input: HashMapInput) = input.smallMap.run {
56+
getOrPut("1") { "" }
57+
getOrPut("2") { "" }
58+
}
59+
60+
@Benchmark
61+
@BenchmarkMode(Mode.Throughput)
62+
fun getThenRemoveEntry(input: HashMapInput) = input.smallMap.run {
63+
getOrPut("1") { "" }
64+
remove("1")
65+
}
66+
}

0 commit comments

Comments
 (0)