Skip to content

Instantly share code, notes, and snippets.

@rednafi
Last active October 30, 2024 07:31
Show Gist options
  • Save rednafi/08fe371ed31072ab0bd96bf51611660a to your computer and use it in GitHub Desktop.
Save rednafi/08fe371ed31072ab0bd96bf51611660a to your computer and use it in GitHub Desktop.
Dysfunctional option pattern in Go
package src
import (
"testing"
)
// Apply functional options pattern
type config struct {
// Required
foo, bar string
// Optional
fizz, buzz int
}
type option func(*config)
func WithFizz(fizz int) option {
return func(c *config) {
c.fizz = fizz
}
}
func WithBuzz(buzz int) option {
return func(c *config) {
c.buzz = buzz
}
}
func NewConfig(foo, bar string, opts ...option) *config {
c := &config{foo: foo, bar: bar}
for _, opt := range opts {
opt(c)
}
return c
}
// Benchmark the functional options pattern
func BenchmarkNewConfig(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewConfig("foo", "bar", WithFizz(1), WithBuzz(2))
}
}
// Dysfunctional options pattern
type configDys struct {
// Required
foo, bar string
// Optional
fizz, buzz int
}
func NewConfigDys(foo, bar string) *configDys {
return &configDys{foo: foo, bar: bar}
}
func (c *configDys) WithFizz(fizz int) *configDys {
c.fizz = fizz
return c
}
func (c *configDys) WithBuzz(buzz int) *configDys {
c.buzz = buzz
return c
}
// Benchmark the dysfunctional options pattern
func BenchmarkNewConfigDys(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewConfigDys("foo", "bar").WithFizz(1).WithBuzz(2)
}
}
@rednafi
Copy link
Author

rednafi commented Mar 6, 2024

Here's the result (ran on a macbook air 15 inch, 16-256 config)

goos: darwin
goarch: arm64
pkg: foo
BenchmarkNewConfig-8            54789004                22.22 ns/op        48 B/op           1 allocs/op
BenchmarkNewConfigDys-8         1000000000               0.2913 ns/op       0 B/op           0 allocs/op
PASS
ok      foo     2.545s

@AlexeyNikitin01
Copy link

My analog test with result:

go test -bench=. -benchtime=100s
goos: linux
goarch: amd64
pkg: internal/testutil/project
cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
BenchmarkFuncOptions-8 36885484 3613 ns/op 336 B/op 2 allocs/op
BenchmarkDisfuncOptions-8 44132131 2549 ns/op 344 B/op 3 allocs/op
PASS
ok internal/testutil/project 345.614s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment