Skip to content

Commit 18259db

Browse files
authored
optimization: avoid NotGiven allocations (#17090)
## Problem I've been working on a library that uses `NotGiven` in the hot path, which ends up producing an extra allocation on every use. I thought JIT compilation would be able to optimize it away but that isn't the case in some benchmarks. For example: Benchmark: https://github.com/fwbrasil/kyo/blob/main/kyo-bench/src/main/scala/kyo/bench/NarrowBindMapBench.scala Flamegraph: https://getkyo.io/dev/profile/4990c20/kyo.bench.NarrowBindMapBench.forkKyo-Throughput/flame-cpu-forward.html ## Solution Make `NotGiven.value` a `val` instead of `def`. ## Notes - I'm assuming the identity of a `NotGiven` object isn't relevant. - Should I use an internal field and keep `NotGiven.value` as `def` to avoid binary compatibility issues?
2 parents 29e229b + 421591f commit 18259db

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

library/src/scala/util/NotGiven.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ trait LowPriorityNotGiven {
3131
}
3232
object NotGiven extends LowPriorityNotGiven {
3333

34+
private val cachedValue = new NotGiven[Nothing]()
35+
3436
/** A value of type `NotGiven` to signal a successful search for `NotGiven[C]` (i.e. a failing
3537
* search for `C`). A reference to this value will be explicitly constructed by Dotty's
3638
* implicit search algorithm
3739
*/
38-
def value: NotGiven[Nothing] = new NotGiven[Nothing]()
40+
def value: NotGiven[Nothing] = cachedValue
3941

4042
/** One of two ambiguous methods used to emulate negation in Scala 2 */
4143
given amb1[T](using ev: T): NotGiven[T] = ???

0 commit comments

Comments
 (0)