1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-27 22:28:29 +02:00
Files
fp-go/v2/option/benchmark_test.go
Dr. Carsten Leue 03d9720a29 fix: optimize performance for option
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2025-11-17 12:19:24 +01:00

210 lines
4.1 KiB
Go

// Copyright (c) 2025 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package option
import (
"testing"
)
// Benchmark basic construction
func BenchmarkSome(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_ = Some(42)
}
}
func BenchmarkNone(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_ = None[int]()
}
}
// Benchmark basic operations
func BenchmarkIsSome(b *testing.B) {
opt := Some(42)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = IsSome(opt)
}
}
func BenchmarkMap(b *testing.B) {
opt := Some(21)
mapper := Map(func(x int) int { return x * 2 })
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper(opt)
}
}
func BenchmarkChain(b *testing.B) {
opt := Some(21)
chainer := Chain(func(x int) Option[int] {
if x > 0 {
return Some(x * 2)
}
return None[int]()
})
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = chainer(opt)
}
}
func BenchmarkFilter(b *testing.B) {
opt := Some(42)
filter := Filter(func(x int) bool { return x > 0 })
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = filter(opt)
}
}
func BenchmarkGetOrElse(b *testing.B) {
opt := Some(42)
getter := GetOrElse(func() int { return 0 })
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = getter(opt)
}
}
// Benchmark collection operations
func BenchmarkTraverseArray_Small(b *testing.B) {
data := []int{1, 2, 3, 4, 5}
traverser := TraverseArray(func(x int) Option[int] {
return Some(x * 2)
})
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = traverser(data)
}
}
func BenchmarkTraverseArray_Large(b *testing.B) {
data := make([]int, 1000)
for i := range data {
data[i] = i
}
traverser := TraverseArray(func(x int) Option[int] {
return Some(x * 2)
})
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = traverser(data)
}
}
func BenchmarkSequenceArray_Small(b *testing.B) {
data := []Option[int]{Some(1), Some(2), Some(3), Some(4), Some(5)}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = SequenceArray(data)
}
}
func BenchmarkCompactArray_Small(b *testing.B) {
data := []Option[int]{Some(1), None[int](), Some(3), None[int](), Some(5)}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = CompactArray(data)
}
}
// Benchmark do-notation
func BenchmarkDoBind(b *testing.B) {
type State struct {
x int
y int
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = MonadChain(
MonadChain(
Of(State{}),
func(s State) Option[State] {
s.x = 10
return Some(s)
},
),
func(s State) Option[State] {
s.y = 20
return Some(s)
},
)
}
}
// Benchmark conversions
func BenchmarkFromPredicate(b *testing.B) {
pred := FromPredicate(func(x int) bool { return x > 0 })
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = pred(42)
}
}
func BenchmarkFromNillable(b *testing.B) {
val := 42
ptr := &val
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = FromNillable(ptr)
}
}
func BenchmarkTryCatch(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = TryCatch(func() (int, error) {
return 42, nil
})
}
}
// Benchmark complex chains
func BenchmarkComplexChain(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = MonadChain(
MonadChain(
MonadChain(
Some(1),
func(x int) Option[int] { return Some(x + 1) },
),
func(x int) Option[int] { return Some(x * 2) },
),
func(x int) Option[int] { return Some(x - 5) },
)
}
}