diff --git a/zstd/decoder_test.go b/zstd/decoder_test.go index c880b61250..30ec9bfee4 100644 --- a/zstd/decoder_test.go +++ b/zstd/decoder_test.go @@ -1415,7 +1415,27 @@ func benchmarkDecoderWithFile(path string, b *testing.B) { } b.Run("multithreaded-writer", func(b *testing.B) { - dec, err := NewReader(nil) + dec, err := NewReader(nil, WithDecoderLowmem(true)) + if err != nil { + b.Fatal(err) + } + b.SetBytes(n) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + err = dec.Reset(bytes.NewBuffer(data)) + if err != nil { + b.Fatal(err) + } + _, err := io.CopyN(ioutil.Discard, dec, n) + if err != nil { + b.Fatal(err) + } + } + }) + + b.Run("multithreaded-writer-himem", func(b *testing.B) { + dec, err := NewReader(nil, WithDecoderLowmem(false)) if err != nil { b.Fatal(err) } @@ -1436,7 +1456,7 @@ func benchmarkDecoderWithFile(path string, b *testing.B) { }) b.Run("singlethreaded-writer", func(b *testing.B) { - dec, err := NewReader(nil, WithDecoderConcurrency(1)) + dec, err := NewReader(nil, WithDecoderConcurrency(1), WithDecoderLowmem(true)) if err != nil { b.Fatal(err) } @@ -1457,7 +1477,28 @@ func benchmarkDecoderWithFile(path string, b *testing.B) { }) b.Run("singlethreaded-writerto", func(b *testing.B) { - dec, err := NewReader(nil, WithDecoderConcurrency(1)) + dec, err := NewReader(nil, WithDecoderConcurrency(1), WithDecoderLowmem(true)) + if err != nil { + b.Fatal(err) + } + + b.SetBytes(n) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + err = dec.Reset(bytes.NewBuffer(data)) + if err != nil { + b.Fatal(err) + } + // io.Copy will use io.WriterTo + _, err := io.Copy(ioutil.Discard, dec) + if err != nil { + b.Fatal(err) + } + } + }) + b.Run("singlethreaded-himem", func(b *testing.B) { + dec, err := NewReader(nil, WithDecoderConcurrency(1), WithDecoderLowmem(false)) if err != nil { b.Fatal(err) } diff --git a/zstd/framedec.go b/zstd/framedec.go index 3ff109cce4..fa0a633f38 100644 --- a/zstd/framedec.go +++ b/zstd/framedec.go @@ -253,10 +253,11 @@ func (d *frameDec) reset(br byteBuffer) error { return ErrWindowSizeTooSmall } d.history.windowSize = int(d.WindowSize) - if d.o.lowMem && d.history.windowSize < maxBlockSize { + if !d.o.lowMem || d.history.windowSize < maxBlockSize { + // Alloc 2x window size if not low-mem, or very small window size. d.history.allocFrameBuffer = d.history.windowSize * 2 - // TODO: Maybe use FrameContent size } else { + // Alloc with one additional block d.history.allocFrameBuffer = d.history.windowSize + maxBlockSize }