diff --git a/pkg/ecs/int-log.go b/pkg/ecs/int-log.go index d1e4e80..4244480 100644 --- a/pkg/ecs/int-log.go +++ b/pkg/ecs/int-log.go @@ -8,6 +8,10 @@ package ecs import "math/bits" -func FastIntLog2(value uint) int { - return bits.Len(value) - 1 +func FastIntLog2(value uint64) int { + return bits.Len64(value) - 1 +} + +func FastestIntLog2(value uint64) int { + return bits.LeadingZeros64(value) ^ 63 } diff --git a/pkg/ecs/int-log_test.go b/pkg/ecs/int-log_test.go index d906f9d..5085b9b 100644 --- a/pkg/ecs/int-log_test.go +++ b/pkg/ecs/int-log_test.go @@ -8,28 +8,45 @@ package ecs import ( "math" + "math/bits" "testing" ) func TestCalcIndex(t *testing.T) { - for i := 0; i <= 100_000_000; i++ { - value := i>>10 + 1 + for i := uint64(0); i <= 100_000_000; i++ { + var value uint64 = i>>10 + 1 want := int(math.Log2(float64(value))) - have := FastIntLog2(uint(value)) + want2 := int(bits.LeadingZeros64(value) ^ 63) + have := bits.Len64(value) - 1 if want != have { t.Fatalf("i: %v, want: %v, got: %v", i, want, have) } + if want2 != have { + t.Fatalf("i: %v, want: %v, got: %v", i, want2, have) + } + } +} + +func BenchmarkFastestLog2(b *testing.B) { + var i uint64 = 1 + for b.Loop() { + _ = FastestIntLog2(i/10 + 1) + i++ } } -func BenchmarkFastLog2(t *testing.B) { - for range t.N { - _ = FastIntLog2(uint(t.N/10 + 1)) +func BenchmarkFastLog2(b *testing.B) { + var i uint64 = 1 + for b.Loop() { + _ = FastIntLog2(i/10 + 1) + i++ } } -func BenchmarkStdMathLog2(t *testing.B) { - for range t.N { - _ = int(math.Log2(float64(t.N/10 + 1))) +func BenchmarkStdMathLog2(b *testing.B) { + var i uint64 = 1 + for b.Loop() { + _ = math.Log2(float64(i/10 + 1)) + i++ } } diff --git a/pkg/ecs/slice.go b/pkg/ecs/slice.go index f084bbf..5cfe011 100644 --- a/pkg/ecs/slice.go +++ b/pkg/ecs/slice.go @@ -60,7 +60,7 @@ func (a *Slice[T]) Set(index int, value T) *T { func (a *Slice[T]) Append(values ...T) []T { a.data = append(a.data, values...) - disCap := 1 << (FastIntLog2(uint(len(a.data))) + 1) + disCap := 1 << (FastIntLog2(uint64(len(a.data))) + 1) if cap(a.data) > disCap { a.data = a.data[:len(a.data):disCap] }