Files
coder/coderd/util/lazy/value.go
Ammar Bandukwala 0d9010e150 chore: fix 30% startup time hit from userpassword (#12769)
pbkdf2 is too expensive to run in init, so this change makes it load
lazily. I introduced a lazy package that I hope to use more in my
`GODEBUG=inittrace=1` adventure.


Benchmark results:

```
$ hyperfine "coder --help" "coder-new --help"
Benchmark 1: coder --help
  Time (mean ± σ):      82.1 ms ±   3.8 ms    [User: 93.3 ms, System: 30.4 ms]
  Range (min … max):    72.2 ms …  90.7 ms    35 runs
 
Benchmark 2: coder-new --help
  Time (mean ± σ):      52.0 ms ±   4.3 ms    [User: 62.4 ms, System: 30.8 ms]
  Range (min … max):    41.9 ms …  62.2 ms    52 runs
 
Summary
  coder-new --help ran
    1.58 ± 0.15 times faster than coder --help
```
2024-03-26 20:47:14 -05:00

29 lines
555 B
Go

// Package lazy provides a lazy value implementation.
// It's useful especially in global variable initialization to avoid
// slowing down the program startup time.
package lazy
import (
"sync"
"sync/atomic"
)
type Value[T any] struct {
once sync.Once
fn func() T
cached atomic.Pointer[T]
}
func (v *Value[T]) Load() T {
v.once.Do(func() {
vv := v.fn()
v.cached.Store(&vv)
})
return *v.cached.Load()
}
// New creates a new lazy value with the given load function.
func New[T any](fn func() T) *Value[T] {
return &Value[T]{fn: fn}
}