8000 Changed HashMap.getOrElseUpdate to only calculate the index once · scala/scala@47cffd3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 47cffd3

Browse files
committed
Changed HashMap.getOrElseUpdate to only calculate the index once
Since groupBy uses this method extensively and suffered a measurable slowdown in 2.12, this modification restores (and exceeds) its original speed, i.e. 2.11.8 30915 ops/s 2.12.0 28268 ops/s 2.12.1 37931 ops/s i.e. this commit is 30% faster than 2.12.0 and 20% faster than 2.11.8, according to a JMH benchmark performing a vector.groupBy(Integer.bitCount) --- (ns/op -> smaller is better) before: Benchmark (size) Mode Cnt Score Error Units s.c.immutable.VectorMapBenchmark.groupBy 100 avgt 20 4369.275 ± 346.054 ns/op s.c.mutable.HashMapBenchmark.getOrElseUpdate_found 100 avgt 20 3604.498 ± 25.567 ns/op s.c.mutable.HashMapBenchmark.getOrElseUpdate_missing 100 avgt 20 4022.128 ± 27.152 ns/op after: Benchmark (size) Mode Cnt Score Error Units s.c.immutable.VectorMapBenchmark.groupBy 100 avgt 20 3062.642 ± 36.108 ns/op s.c.mutable.HashMapBenchmark.getOrElseUpdate_found 100 avgt 20 2829.737 ± 45.172 ns/op s.c.mutable.HashMapBenchmark.getOrElseUpdate_missing 100 avgt 20 2212.019 ± 153.345 ns/op
1 parent 4ed4b08 commit 47cffd3

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

src/library/scala/collection/mutable/HashMap.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,18 @@ extends AbstractMap[A, B]
7272
else Some(e.value)
7373
}
7474

75+
override def getOrElseUpdate(key: A, defaultValue: => B): B = {
76+
val i = index(elemHashCode(key))
77+
val entry = findEntry0(key, i)
78+
if (entry != null)
79+
entry.value
80+
else {
81+
val newEntry = createNewEntry(key, defaultValue)
82+
addEntry0(newEntry, i)
83+
newEntry.value
84+
}
85+
}
86+
7587
override def put(key: A, value: B): Option[B] = {
7688
val e = findOrAddEntry(key, value)
7789
if (e eq null) None

src/library/scala/collection/mutable/HashTable.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU
131131
protected def findEntry(key: A): Entry =
132132
findEntry0(key, index(elemHashCode(key)))
133133

134-
private[this] def findEntry0(key: A, h: Int): Entry = {
134+
protected[this] final def findEntry0(key: A, h: Int): Entry = {
135135
var e = table(h).asInstanceOf[Entry]
136136
while (e != null && !elemEquals(e.key, key)) e = e.next
137137
e
@@ -145,7 +145,7 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU
145145
addEntry0(e, index(elemHashCode(e.key)))
146146
}
147147

148-
private[this] def addEntry0(e: Entry, h: Int) {
148+
protected[this] final def addEntry0(e: Entry, h: Int) {
149149
e.next = table(h).asInstanceOf[Entry]
150150
table(h) = e
151151
tableSize = tableSize + 1

0 commit comments

Comments
 (0)
0