compress/bzip2: make decoding faster

Issue 6754 reports that Go bzip2 Decode function is much slower
(about 2.5x in go1.5) than the Python equivalent (which is
actually just a wrapper around the usual C library) on random data.

Profiling the code shows that half a dozen of CMP instructions in a
tight loop are responsibile for most of the execution time.

This patch reduces the number of branches of the loop, greatly
improving performance on random data and speeding up decoding of
real data.

name            old time/op    new time/op    delta
DecodeDigits-4    9.28ms ± 1%    8.05ms ± 1%  -13.18%  (p=0.000 n=15+14)
DecodeTwain-4     28.9ms ± 2%    26.4ms ± 1%   -8.57%  (p=0.000 n=15+14)
DecodeRand-4      3.94ms ± 1%    3.06ms ± 1%  -22.45%  (p=0.000 n=15+14)

name            old speed      new speed      delta
DecodeDigits-4  4.65MB/s ± 1%  5.36MB/s ± 1%  +15.21%  (p=0.000 n=13+14)
DecodeTwain-4   4.32MB/s ± 2%  4.72MB/s ± 1%   +9.36%  (p=0.000 n=15+14)
DecodeRand-4    4.27MB/s ± 1%  5.51MB/s ± 1%  +28.86%  (p=0.000 n=15+14)

I've run some benchmark comparing Go bzip2 implementation with the
usual Linux bzip2 command (which is written in C). On my machine
this patch brings go1.5
  from ~2.26x to ~1.50x of bzip2 time (on 64MB  random data)
  from ~1.70x to ~1.50x of bzip2 time (on 100MB english text)
  from ~2.00x to ~1.88x of bzip2 time (on 64MB  /dev/zero data)

Fixes #6754

Change-Id: I3cb12d2c0c2243c1617edef1edc88f05f91d26d1
Reviewed-on: https://go-review.googlesource.com/13853
Reviewed-by: Nigel Tao <nigeltao@golang.org>
4 files changed
tree: 8d7c72fcd9d8db73a6be58f4fa8df912445010d5
  1. api/
  2. doc/
  3. lib/
  4. misc/
  5. src/
  6. test/
  7. .gitattributes
  8. .gitignore
  9. AUTHORS
  10. CONTRIBUTING.md
  11. CONTRIBUTORS
  12. favicon.ico
  13. LICENSE
  14. PATENTS
  15. README.md
  16. robots.txt
README.md

The Go Programming Language

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

Gopher image

For documentation about how to install and use Go, visit https://golang.org/ or load doc/install-source.html in your web browser.

Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.

Please report issues here: https://golang.org/issue/new

Go is the work of hundreds of contributors. We appreciate your help!

To contribute, please read the contribution guidelines: https://golang.org/doc/contribute.html

Please note that we do not use pull requests.

Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.


Binary Distribution Notes

If you have just untarred a binary Go distribution, you need to set the environment variable $GOROOT to the full path of the go directory (the one containing this file). You can omit the variable if you unpack it into /usr/local/go, or if you rebuild from sources by running all.bash (see doc/install-source.html). You should also add the Go binary directory $GOROOT/bin to your shell's path.

For example, if you extracted the tar file into $HOME/go, you might put the following in your .profile:

export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin

See https://golang.org/doc/install or doc/install.html for more details.