From abbecf49d6dce5d430b227bf8fa4016b15d4fd1c Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 10 Feb 2023 07:59:15 +0300 Subject: [PATCH] [#31] fstree: Speedup string-to-address conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` name old time/op new time/op delta _addressFromString-8 1.25µs ±30% 1.02µs ± 6% -18.49% (p=0.000 n=9+9) name old alloc/op new alloc/op delta _addressFromString-8 352B ± 0% 256B ± 0% -27.27% (p=0.000 n=9+10) name old allocs/op new allocs/op delta _addressFromString-8 6.00 ± 0% 4.00 ± 0% -33.33% (p=0.000 n=10+10) ``` Also, assure compiler that `s` doesn't escape: Before this commit: ``` ./fstree.go:74:24: leaking param: s ./fstree.go:90:6: moved to heap: addr ``` After this commit: ``` ./fstree.go:74:24: s does not escape ``` Signed-off-by: Evgenii Stratonikov --- .../blobstor/fstree/fstree.go | 24 +++++++++---------- .../blobstor/fstree/fstree_test.go | 16 ++++++++++++- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pkg/local_object_storage/blobstor/fstree/fstree.go b/pkg/local_object_storage/blobstor/fstree/fstree.go index 5d7094d4..d129bf98 100644 --- a/pkg/local_object_storage/blobstor/fstree/fstree.go +++ b/pkg/local_object_storage/blobstor/fstree/fstree.go @@ -71,27 +71,27 @@ func stringifyAddress(addr oid.Address) string { return addr.Object().EncodeToString() + "." + addr.Container().EncodeToString() } -func addressFromString(s string) (*oid.Address, error) { - ss := strings.SplitN(s, ".", 2) - if len(ss) != 2 { - return nil, errors.New("invalid address") +func addressFromString(s string) (oid.Address, error) { + i := strings.IndexByte(s, '.') + if i == -1 { + return oid.Address{}, errors.New("invalid address") } var obj oid.ID - if err := obj.DecodeString(ss[0]); err != nil { - return nil, err + if err := obj.DecodeString(s[:i]); err != nil { + return oid.Address{}, err } var cnr cid.ID - if err := cnr.DecodeString(ss[1]); err != nil { - return nil, err + if err := cnr.DecodeString(s[i+1:]); err != nil { + return oid.Address{}, err } var addr oid.Address addr.SetObject(obj) addr.SetContainer(cnr) - return &addr, nil + return addr, nil } // Iterate iterates over all stored objects. @@ -135,7 +135,7 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm) } if prm.LazyHandler != nil { - err = prm.LazyHandler(*addr, func() ([]byte, error) { + err = prm.LazyHandler(addr, func() ([]byte, error) { return os.ReadFile(filepath.Join(curPath...)) }) } else { @@ -147,7 +147,7 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm) if err != nil { if prm.IgnoreErrors { if prm.ErrorHandler != nil { - return prm.ErrorHandler(*addr, err) + return prm.ErrorHandler(addr, err) } continue } @@ -155,7 +155,7 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm) } err = prm.Handler(common.IterationElement{ - Address: *addr, + Address: addr, ObjectData: data, StorageID: []byte{}, }) diff --git a/pkg/local_object_storage/blobstor/fstree/fstree_test.go b/pkg/local_object_storage/blobstor/fstree/fstree_test.go index 4bfcc0a9..97fd6032 100644 --- a/pkg/local_object_storage/blobstor/fstree/fstree_test.go +++ b/pkg/local_object_storage/blobstor/fstree/fstree_test.go @@ -12,5 +12,19 @@ func TestAddressToString(t *testing.T) { s := stringifyAddress(addr) actual, err := addressFromString(s) require.NoError(t, err) - require.Equal(t, addr, *actual) + require.Equal(t, addr, actual) +} + +func Benchmark_addressFromString(b *testing.B) { + addr := oidtest.Address() + s := stringifyAddress(addr) + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := addressFromString(s) + if err != nil { + b.Fatalf("benchmark error: %v", err) + } + } }