From 7ce89d19ed780e51e2460b1b0a8f550f12cf0b05 Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Mon, 9 Mar 2020 15:52:45 -0400 Subject: [PATCH 01/11] Fixing prof --- .../ts/m3db/encoded_step_iterator_test.go | 84 +++++++++++-------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/src/query/ts/m3db/encoded_step_iterator_test.go b/src/query/ts/m3db/encoded_step_iterator_test.go index 5b523045a2..8a7fb30277 100644 --- a/src/query/ts/m3db/encoded_step_iterator_test.go +++ b/src/query/ts/m3db/encoded_step_iterator_test.go @@ -398,6 +398,7 @@ func (t iterType) name(name string) string { } type reset func() +type stop func() // newTestOptions provides options with very small/non-existent pools // so that memory profiles don't get cluttered with pooled allocated objects. @@ -423,7 +424,7 @@ func newTestOptions() Options { return newOptions(bytesPool, iteratorPools) } -func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) { +func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset, stop) { var ( seriesCount = 1000 replicasCount = 3 @@ -509,6 +510,39 @@ func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) { } usePools := t == stepParallel + + opts := newTestOptions() + if usePools { + poolOpts := xsync.NewPooledWorkerPoolOptions() + readWorkerPools, err := xsync.NewPooledWorkerPool(1024, poolOpts) + require.NoError(b, err) + readWorkerPools.Init() + opts = opts.SetReadWorkerPool(readWorkerPools) + } + + for _, reset := range itersReset { + reset() + } + + block, err := NewEncodedBlock(iters, models.Bounds{ + Start: start, + StepSize: stepSize, + Duration: window, + }, false, block.NewResultMetadata(), opts) + + require.NoError(b, err) + return block, func() { + for _, reset := range itersReset { + reset() + } + }, + setupProf(usePools, iterations) +} + +func setupProf(usePools bool, iterations int) stop { + var pCPU, pMem interface { + Stop() + } if os.Getenv("PROFILE_TEST_CPU") == "true" { key := profileTakenKey{ profile: "cpu", @@ -516,8 +550,7 @@ func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) { iterations: iterations, } if v := profilesTaken[key]; v == 2 { - p := profile.Start(profile.CPUProfile) - defer p.Stop() + pCPU = profile.Start(profile.CPUProfile) } profilesTaken[key] = profilesTaken[key] + 1 @@ -531,42 +564,25 @@ func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) { } if v := profilesTaken[key]; v == 2 { - p := profile.Start(profile.MemProfile) - defer p.Stop() + pMem = profile.Start(profile.MemProfile) } profilesTaken[key] = profilesTaken[key] + 1 } - - opts := newTestOptions() - if usePools { - poolOpts := xsync.NewPooledWorkerPoolOptions() - readWorkerPools, err := xsync.NewPooledWorkerPool(1024, poolOpts) - require.NoError(b, err) - readWorkerPools.Init() - opts = opts.SetReadWorkerPool(readWorkerPools) - } - - for _, reset := range itersReset { - reset() - } - - block, err := NewEncodedBlock(iters, models.Bounds{ - Start: start, - StepSize: stepSize, - Duration: window, - }, false, block.NewResultMetadata(), opts) - - require.NoError(b, err) - return block, func() { - for _, reset := range itersReset { - reset() + return func() { + if pCPU != nil { + pCPU.Stop() + } + if pMem != nil { + pMem.Stop() } } } func benchmarkNextIteration(b *testing.B, iterations int, t iterType) { - bl, reset := setupBlock(b, iterations, t) + bl, reset, close := setupBlock(b, iterations, t) + defer close() + if t == seriesSequential { it, err := bl.SeriesIter() require.NoError(b, err) @@ -673,13 +689,13 @@ var ( */ func BenchmarkNextIteration(b *testing.B) { iterTypes := []iterType{ - stepSequential, - stepParallel, + // stepSequential, + // stepParallel, seriesSequential, - seriesBatch, + // seriesBatch, } - for _, s := range []int{10, 100, 200, 500, 1000, 2000} { + for _, s := range []int{10} { for _, t := range iterTypes { name := t.name(fmt.Sprintf("%d", s)) b.Run(name, func(b *testing.B) { From fcb9927ba6aa05586c8c2651a80dd5198bdb807e Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 13:06:12 -0400 Subject: [PATCH 02/11] WIP 1 --- src/dbnode/encoding/istream.go | 32 ++++++++++++++++--- src/dbnode/encoding/m3tsz/encoder.go | 8 ++++- src/dbnode/ts/segment.go | 18 +++++++++++ src/dbnode/x/xio/segment_reader.go | 8 ++--- .../ts/m3db/encoded_step_iterator_test.go | 5 +-- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index cc6686c409..0ab3370847 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -22,6 +22,7 @@ package encoding import ( "bufio" + "encoding/binary" "io" "math" ) @@ -31,12 +32,13 @@ type istream struct { r *bufio.Reader // encoded stream err error // error encountered current byte // current byte we are working off of + buffer []byte // current byte we are working off of remaining int // bits remaining in current to be read } // NewIStream creates a new Istream func NewIStream(reader io.Reader, bufioSize int) IStream { - return &istream{r: bufio.NewReaderSize(reader, bufioSize)} + return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, 8, 8)} } // ReadBit reads the next Bit @@ -98,16 +100,36 @@ func (is *istream) ReadBits(numBits int) (uint64, error) { return 0, is.err } + //var res uint64 + //fmt.Println("NUM", numBits) var res uint64 - for numBits >= 8 { - byteRead, err := is.ReadByte() + numBytes := numBits / 8 + numBits = numBits % 8 + if numBytes > 0 { + fullBytes := is.buffer[0:numBytes] + _, err := is.Read(fullBytes) if err != nil { return 0, err } - res = (res << 8) | uint64(byteRead) - numBits -= 8 + // var res2 uint64 + // for _, b := range fullBytes { + // res2 = (res2 << 8) | uint64(b) + // } + res = binary.BigEndian.Uint64(is.buffer) + // if res != res2 { + // panic(fmt.Sprintf("A %d %d", int(res), int(res2))) + // } } + // for numBits >= 8 { + // byteRead, err := is.ReadByte() + // if err != nil { + // return 0, err + // } + // res = (res << 8) | uint64(byteRead) + // numBits -= 8 + // } + for numBits > 0 { // This is equivalent to calling is.ReadBit() in a loop but some manual inlining // has been performed to optimize this loop as its heavily used in the hot path. diff --git a/src/dbnode/encoding/m3tsz/encoder.go b/src/dbnode/encoding/m3tsz/encoder.go index 302c43be16..24c732f6ae 100644 --- a/src/dbnode/encoding/m3tsz/encoder.go +++ b/src/dbnode/encoding/m3tsz/encoder.go @@ -430,5 +430,11 @@ func (enc *encoder) segmentTakeOwnership() ts.Segment { // NB(r): Finalize the head bytes whether this is by ref or copy. If by // ref we have no ref to it anymore and if by copy then the owner should // be finalizing the bytes when the segment is finalized. - return ts.NewSegment(head, tail, 0, ts.FinalizeHead) + head.IncRef() + abc := head.Bytes() + head.DecRef() + tail.IncRef() + def := tail.Bytes() + tail.DecRef() + return ts.NewRawSegment(abc, def, 0, ts.FinalizeHead) } diff --git a/src/dbnode/ts/segment.go b/src/dbnode/ts/segment.go index 285fed4920..c53c4940c3 100644 --- a/src/dbnode/ts/segment.go +++ b/src/dbnode/ts/segment.go @@ -36,6 +36,10 @@ type Segment struct { Head checked.Bytes // Tail is the tail of the segment. Tail checked.Bytes + // RawHead is the head of the segment. + RawHead []byte + // RawTail is the tail of the segment. + RawTail []byte // SegmentFlags declares whether to finalize when finalizing the segment. Flags SegmentFlags // checksum is the checksum for the segment. @@ -94,6 +98,20 @@ func NewSegment( } } +// NewRawSegment creates a new RawSegment. +func NewRawSegment( + head, tail []byte, + checksum uint32, + flags SegmentFlags, +) Segment { + return Segment{ + RawHead: head, + RawTail: tail, + Flags: flags, + checksum: checksum, + } +} + // Len returns the length of the head and tail. func (s *Segment) Len() int { var total int diff --git a/src/dbnode/x/xio/segment_reader.go b/src/dbnode/x/xio/segment_reader.go index 352c8feeea..cdda51485c 100644 --- a/src/dbnode/x/xio/segment_reader.go +++ b/src/dbnode/x/xio/segment_reader.go @@ -51,11 +51,11 @@ func (sr *segmentReader) Read(b []byte) (int, error) { return 0, nil } - if b := sr.segment.Head; b != nil && len(sr.lazyHead) == 0 { - sr.lazyHead = b.Bytes() + if b := sr.segment.RawHead; b != nil && len(sr.lazyHead) == 0 { + sr.lazyHead = b } - if b := sr.segment.Tail; b != nil && len(sr.lazyTail) == 0 { - sr.lazyTail = b.Bytes() + if b := sr.segment.RawTail; b != nil && len(sr.lazyTail) == 0 { + sr.lazyTail = b } nh, nt := len(sr.lazyHead), len(sr.lazyTail) diff --git a/src/query/ts/m3db/encoded_step_iterator_test.go b/src/query/ts/m3db/encoded_step_iterator_test.go index 8a7fb30277..bc5add3f65 100644 --- a/src/query/ts/m3db/encoded_step_iterator_test.go +++ b/src/query/ts/m3db/encoded_step_iterator_test.go @@ -689,13 +689,10 @@ var ( */ func BenchmarkNextIteration(b *testing.B) { iterTypes := []iterType{ - // stepSequential, - // stepParallel, seriesSequential, - // seriesBatch, } - for _, s := range []int{10} { + for _, s := range []int{500} { for _, t := range iterTypes { name := t.name(fmt.Sprintf("%d", s)) b.Run(name, func(b *testing.B) { From e1787ac186136728f568e521cc5c779b3e74f74e Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 13:09:34 -0400 Subject: [PATCH 03/11] WIP 2 --- src/dbnode/encoding/m3tsz/encoder.go | 8 +------- src/dbnode/ts/segment.go | 18 ------------------ src/dbnode/x/xio/segment_reader.go | 8 ++++---- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/dbnode/encoding/m3tsz/encoder.go b/src/dbnode/encoding/m3tsz/encoder.go index 24c732f6ae..302c43be16 100644 --- a/src/dbnode/encoding/m3tsz/encoder.go +++ b/src/dbnode/encoding/m3tsz/encoder.go @@ -430,11 +430,5 @@ func (enc *encoder) segmentTakeOwnership() ts.Segment { // NB(r): Finalize the head bytes whether this is by ref or copy. If by // ref we have no ref to it anymore and if by copy then the owner should // be finalizing the bytes when the segment is finalized. - head.IncRef() - abc := head.Bytes() - head.DecRef() - tail.IncRef() - def := tail.Bytes() - tail.DecRef() - return ts.NewRawSegment(abc, def, 0, ts.FinalizeHead) + return ts.NewSegment(head, tail, 0, ts.FinalizeHead) } diff --git a/src/dbnode/ts/segment.go b/src/dbnode/ts/segment.go index c53c4940c3..285fed4920 100644 --- a/src/dbnode/ts/segment.go +++ b/src/dbnode/ts/segment.go @@ -36,10 +36,6 @@ type Segment struct { Head checked.Bytes // Tail is the tail of the segment. Tail checked.Bytes - // RawHead is the head of the segment. - RawHead []byte - // RawTail is the tail of the segment. - RawTail []byte // SegmentFlags declares whether to finalize when finalizing the segment. Flags SegmentFlags // checksum is the checksum for the segment. @@ -98,20 +94,6 @@ func NewSegment( } } -// NewRawSegment creates a new RawSegment. -func NewRawSegment( - head, tail []byte, - checksum uint32, - flags SegmentFlags, -) Segment { - return Segment{ - RawHead: head, - RawTail: tail, - Flags: flags, - checksum: checksum, - } -} - // Len returns the length of the head and tail. func (s *Segment) Len() int { var total int diff --git a/src/dbnode/x/xio/segment_reader.go b/src/dbnode/x/xio/segment_reader.go index cdda51485c..352c8feeea 100644 --- a/src/dbnode/x/xio/segment_reader.go +++ b/src/dbnode/x/xio/segment_reader.go @@ -51,11 +51,11 @@ func (sr *segmentReader) Read(b []byte) (int, error) { return 0, nil } - if b := sr.segment.RawHead; b != nil && len(sr.lazyHead) == 0 { - sr.lazyHead = b + if b := sr.segment.Head; b != nil && len(sr.lazyHead) == 0 { + sr.lazyHead = b.Bytes() } - if b := sr.segment.RawTail; b != nil && len(sr.lazyTail) == 0 { - sr.lazyTail = b + if b := sr.segment.Tail; b != nil && len(sr.lazyTail) == 0 { + sr.lazyTail = b.Bytes() } nh, nt := len(sr.lazyHead), len(sr.lazyTail) From 701d39d0c6dc969c8359688adce276a1908f07bd Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 13:50:19 -0400 Subject: [PATCH 04/11] WIP 3 --- src/dbnode/encoding/istream.go | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index 0ab3370847..fb5bedcb1f 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -100,8 +100,6 @@ func (is *istream) ReadBits(numBits int) (uint64, error) { return 0, is.err } - //var res uint64 - //fmt.Println("NUM", numBits) var res uint64 numBytes := numBits / 8 numBits = numBits % 8 @@ -111,25 +109,15 @@ func (is *istream) ReadBits(numBits int) (uint64, error) { if err != nil { return 0, err } - // var res2 uint64 - // for _, b := range fullBytes { - // res2 = (res2 << 8) | uint64(b) - // } - res = binary.BigEndian.Uint64(is.buffer) - // if res != res2 { - // panic(fmt.Sprintf("A %d %d", int(res), int(res2))) - // } + if numBytes == 8 { + res = binary.BigEndian.Uint64(fullBytes) + } else { + for _, b := range fullBytes { + res = (res << 8) | uint64(b) + } + } } - // for numBits >= 8 { - // byteRead, err := is.ReadByte() - // if err != nil { - // return 0, err - // } - // res = (res << 8) | uint64(byteRead) - // numBits -= 8 - // } - for numBits > 0 { // This is equivalent to calling is.ReadBit() in a loop but some manual inlining // has been performed to optimize this loop as its heavily used in the hot path. From 7eeda348876eec622002b3edc646c7706d7a458e Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 14:03:35 -0400 Subject: [PATCH 05/11] WIP 4 --- src/dbnode/encoding/istream.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index fb5bedcb1f..e1eebcb2bb 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -27,6 +27,10 @@ import ( "math" ) +const ( + numBytesInInt64 = 8 +) + // istream encapsulates a readable stream. type istream struct { r *bufio.Reader // encoded stream @@ -38,7 +42,7 @@ type istream struct { // NewIStream creates a new Istream func NewIStream(reader io.Reader, bufioSize int) IStream { - return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, 8, 8)} + return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, numBytesInInt64, numBytesInInt64)} } // ReadBit reads the next Bit @@ -104,15 +108,17 @@ func (is *istream) ReadBits(numBits int) (uint64, error) { numBytes := numBits / 8 numBits = numBits % 8 if numBytes > 0 { - fullBytes := is.buffer[0:numBytes] - _, err := is.Read(fullBytes) + // Use Read call rather than individual ReadByte calls since it has + // optimized path for when the iterator is aligned on a byte boundary. + bytes := is.buffer[0:numBytes] + _, err := is.Read(bytes) if err != nil { return 0, err } - if numBytes == 8 { - res = binary.BigEndian.Uint64(fullBytes) + if numBytes == numBytesInInt64 { + res = binary.BigEndian.Uint64(bytes) } else { - for _, b := range fullBytes { + for _, b := range bytes { res = (res << 8) | uint64(b) } } From 2aeb9b5773c545048d84cffade0d5f362df90085 Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 14:04:41 -0400 Subject: [PATCH 06/11] WIP 5 --- src/dbnode/encoding/istream.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index e1eebcb2bb..356be0de4a 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -111,11 +111,11 @@ func (is *istream) ReadBits(numBits int) (uint64, error) { // Use Read call rather than individual ReadByte calls since it has // optimized path for when the iterator is aligned on a byte boundary. bytes := is.buffer[0:numBytes] - _, err := is.Read(bytes) + read, err := is.Read(bytes) if err != nil { return 0, err } - if numBytes == numBytesInInt64 { + if read == numBytesInInt64 { res = binary.BigEndian.Uint64(bytes) } else { for _, b := range bytes { From d9e021c1758ccfb001acffce9e96d76040cc326e Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 14:39:05 -0400 Subject: [PATCH 07/11] Comment --- src/dbnode/encoding/istream.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index 356be0de4a..7dd325bb5f 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -36,7 +36,7 @@ type istream struct { r *bufio.Reader // encoded stream err error // error encountered current byte // current byte we are working off of - buffer []byte // current byte we are working off of + buffer []byte // buffer for reading in multiple bytes remaining int // bits remaining in current to be read } From d2c9c98cf17cffa656841c8dd92e9b8f74d1c4f6 Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 15:43:29 -0400 Subject: [PATCH 08/11] Merged in master 2 --- src/query/ts/m3db/encoded_step_iterator_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/query/ts/m3db/encoded_step_iterator_test.go b/src/query/ts/m3db/encoded_step_iterator_test.go index 239f487653..02b7af1568 100644 --- a/src/query/ts/m3db/encoded_step_iterator_test.go +++ b/src/query/ts/m3db/encoded_step_iterator_test.go @@ -686,10 +686,13 @@ var ( */ func BenchmarkNextIteration(b *testing.B) { iterTypes := []iterType{ + stepSequential, + stepParallel, seriesSequential, + seriesBatch, } - for _, s := range []int{500} { + for _, s := range []int{10, 100, 200, 500, 1000, 2000} { for _, t := range iterTypes { name := t.name(fmt.Sprintf("%d", s)) b.Run(name, func(b *testing.B) { From 04a60395e999ee0e3c056b6b7492ec0d7695dba0 Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Wed, 11 Mar 2020 17:22:10 -0400 Subject: [PATCH 09/11] Feedback 1 --- src/dbnode/encoding/istream.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index 01d9c7f5de..553d4d1e77 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -27,10 +27,6 @@ import ( "math" ) -const ( - numBytesInInt64 = 8 -) - // istream encapsulates a readable stream. type istream struct { r *bufio.Reader // encoded stream @@ -42,7 +38,11 @@ type istream struct { // NewIStream creates a new Istream func NewIStream(reader io.Reader, bufioSize int) IStream { - return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, numBytesInInt64, numBytesInInt64)} + return &istream{ + r: bufio.NewReaderSize(reader, bufioSize), + // Buffer meant to hold uint64 size of bytes. + buffer: make([]byte, 8), + } } // ReadBit reads the next Bit @@ -105,7 +105,6 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) { } var res uint64 numBytes := numBits / 8 - numBits = numBits % 8 if numBytes > 0 { // Use Read call rather than individual ReadByte calls since it has // optimized path for when the iterator is aligned on a byte boundary. @@ -114,7 +113,7 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) { if err != nil { return 0, err } - if read == numBytesInInt64 { + if read == 8 { res = binary.BigEndian.Uint64(bytes) } else { for _, b := range bytes { @@ -123,6 +122,7 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) { } } + numBits = numBits % 8 for numBits > 0 { // This is equivalent to calling is.ReadBit() in a loop but some manual inlining // has been performed to optimize this loop as its heavily used in the hot path. From e93f3916fc34ec0f7bc0048fbc9586a41105a5cc Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Mon, 16 Mar 2020 11:22:40 -0400 Subject: [PATCH 10/11] Inlining 8 byte conversion --- src/dbnode/encoding/istream.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index 553d4d1e77..c2017c7275 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -22,7 +22,6 @@ package encoding import ( "bufio" - "encoding/binary" "io" "math" ) @@ -114,7 +113,10 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) { return 0, err } if read == 8 { - res = binary.BigEndian.Uint64(bytes) + // Inlined copy of native code for performance: binary.BigEndian.Uint64(bytes). + _ = bytes[7] + res = uint64(bytes[7]) | uint64(bytes[6])<<8 | uint64(bytes[5])<<16 | uint64(bytes[4])<<24 | + uint64(bytes[3])<<32 | uint64(bytes[2])<<40 | uint64(bytes[1])<<48 | uint64(bytes[0])<<56 } else { for _, b := range bytes { res = (res << 8) | uint64(b) From bd55766011d1839714a69ef7b465e607408a750d Mon Sep 17 00:00:00 2001 From: Ryan Allen <rallen090@gmail.com> Date: Mon, 16 Mar 2020 14:08:24 -0400 Subject: [PATCH 11/11] Removing inlining --- src/dbnode/encoding/istream.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go index c2017c7275..96de36345b 100644 --- a/src/dbnode/encoding/istream.go +++ b/src/dbnode/encoding/istream.go @@ -108,19 +108,12 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) { // Use Read call rather than individual ReadByte calls since it has // optimized path for when the iterator is aligned on a byte boundary. bytes := is.buffer[0:numBytes] - read, err := is.Read(bytes) + _, err := is.Read(bytes) if err != nil { return 0, err } - if read == 8 { - // Inlined copy of native code for performance: binary.BigEndian.Uint64(bytes). - _ = bytes[7] - res = uint64(bytes[7]) | uint64(bytes[6])<<8 | uint64(bytes[5])<<16 | uint64(bytes[4])<<24 | - uint64(bytes[3])<<32 | uint64(bytes[2])<<40 | uint64(bytes[1])<<48 | uint64(bytes[0])<<56 - } else { - for _, b := range bytes { - res = (res << 8) | uint64(b) - } + for _, b := range bytes { + res = (res << 8) | uint64(b) } }