From 1f4061c0e2d13a0852f170749a1aeacc60646241 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 26 Apr 2023 11:29:33 +0300 Subject: [PATCH] [#285] blobonicza: Optimize upperPowerOfTwo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The real reason is this: ``` pkg/local_object_storage/blobovnicza/sizes.go:36:69 revive empty-block: this block is empty, you can remove it ``` Didn't want to make this function longer or to add `nolint`, thus this change. To justify: ``` UpperBound/size=1-8 0.4924n ± 1% 0.2472n ± 2% -49.80% (p=0.000 n=10) UpperBound/size=1023-8 0.4936n ± 3% 0.2442n ± 1% -50.52% (p=0.000 n=10) UpperBound/size=66560-8 0.8201n ± 2% 0.2436n ± 1% -70.29% (p=0.000 n=10) UpperBound/size=41943040-8 6.6900n ± 5% 0.2432n ± 0% -96.36% (p=0.000 n=10) geomean 1.075n 0.2446n -77.24% ``` Signed-off-by: Evgenii Stratonikov --- pkg/local_object_storage/blobovnicza/sizes.go | 9 +++++---- pkg/local_object_storage/blobovnicza/sizes_test.go | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/pkg/local_object_storage/blobovnicza/sizes.go b/pkg/local_object_storage/blobovnicza/sizes.go index 5b89760c6..82454fa28 100644 --- a/pkg/local_object_storage/blobovnicza/sizes.go +++ b/pkg/local_object_storage/blobovnicza/sizes.go @@ -3,6 +3,7 @@ package blobovnicza import ( "encoding/binary" "fmt" + "math/bits" "strconv" ) @@ -31,11 +32,11 @@ func bucketForSize(sz uint64) []byte { return bucketKeyFromBounds(upperPowerOfTwo(sz)) } -func upperPowerOfTwo(v uint64) (upperBound uint64) { - for upperBound = firstBucketBound; upperBound < v; upperBound *= 2 { +func upperPowerOfTwo(v uint64) uint64 { + if v <= firstBucketBound { + return firstBucketBound } - - return + return 1 << bits.Len64(v-1) } func (b *Blobovnicza) incSize(sz uint64) { diff --git a/pkg/local_object_storage/blobovnicza/sizes_test.go b/pkg/local_object_storage/blobovnicza/sizes_test.go index c218dc638..2bf451f12 100644 --- a/pkg/local_object_storage/blobovnicza/sizes_test.go +++ b/pkg/local_object_storage/blobovnicza/sizes_test.go @@ -1,6 +1,7 @@ package blobovnicza import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -36,3 +37,13 @@ func TestSizes(t *testing.T) { require.Equal(t, bucketKeyFromBounds(item.upperBound), bucketForSize(item.sz)) } } + +func BenchmarkUpperBound(b *testing.B) { + for _, size := range []uint64{1, 1023, 65 * 1024, 40 * 1024 * 1024} { + b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = upperPowerOfTwo(size) + } + }) + } +}