]> Cypherpunks repositories - gostls13.git/commitdiff
compress/flate: faster version of forwardCopy
authorKeith Randall <khr@golang.org>
Sat, 18 May 2013 22:28:27 +0000 (15:28 -0700)
committerKeith Randall <khr@golang.org>
Sat, 18 May 2013 22:28:27 +0000 (15:28 -0700)
benchmark                           old ns/op    new ns/op    delta
BenchmarkDecodeDigitsSpeed1e4          197767       203490   +2.89%
BenchmarkDecodeDigitsSpeed1e5         1873969      1912761   +2.07%
BenchmarkDecodeDigitsSpeed1e6        18922760     19021056   +0.52%
BenchmarkDecodeDigitsDefault1e4        194975       197054   +1.07%
BenchmarkDecodeDigitsDefault1e5       1704262      1719988   +0.92%
BenchmarkDecodeDigitsDefault1e6      16618354     16351957   -1.60%
BenchmarkDecodeDigitsCompress1e4       195281       194626   -0.34%
BenchmarkDecodeDigitsCompress1e5      1694364      1702372   +0.47%
BenchmarkDecodeDigitsCompress1e6     16463347     16492126   +0.17%
BenchmarkDecodeTwainSpeed1e4           200653       200127   -0.26%
BenchmarkDecodeTwainSpeed1e5          1861385      1759632   -5.47%
BenchmarkDecodeTwainSpeed1e6         18255769     17186679   -5.86%
BenchmarkDecodeTwainDefault1e4         189080       185157   -2.07%
BenchmarkDecodeTwainDefault1e5        1559222      1461465   -6.27%
BenchmarkDecodeTwainDefault1e6       14792125     13879051   -6.17%
BenchmarkDecodeTwainCompress1e4        188881       185151   -1.97%
BenchmarkDecodeTwainCompress1e5       1537031      1456945   -5.21%
BenchmarkDecodeTwainCompress1e6      14805972     13405094   -9.46%
BenchmarkPaeth                          4            4   -0.89%
BenchmarkDecodeGray                964679       937244   -2.84%
BenchmarkDecodeNRGBAGradient      3753769      3646416   -2.86%
BenchmarkDecodeNRGBAOpaque        3165856      2981300   -5.83%
BenchmarkDecodePaletted            713950       691984   -3.08%
BenchmarkDecodeRGB                3051718      2924260   -4.18%

R=nigeltao, bradfitz
CC=golang-dev, raph
https://golang.org/cl/9425046

src/pkg/compress/flate/copy.go
src/pkg/compress/flate/copy_test.go
src/pkg/compress/flate/inflate.go

index 06e5d2e66d9fd54284a1f8c8aa3dd7110ffe715d..a3200a8f49e8cf106cbc77b0c1029c69877f797a 100644 (file)
@@ -6,12 +6,27 @@ package flate
 
 // forwardCopy is like the built-in copy function except that it always goes
 // forward from the start, even if the dst and src overlap.
-func forwardCopy(dst, src []byte) int {
-       if len(src) > len(dst) {
-               src = src[:len(dst)]
+// It is equivalent to:
+//   for i := 0; i < n; i++ {
+//     mem[dst+i] = mem[src+i]
+//   }
+func forwardCopy(mem []byte, dst, src, n int) {
+       if dst <= src {
+               copy(mem[dst:dst+n], mem[src:src+n])
+               return
        }
-       for i, x := range src {
-               dst[i] = x
+       for {
+               if dst >= src+n {
+                       copy(mem[dst:dst+n], mem[src:src+n])
+                       return
+               }
+               // There is some forward overlap.  The destination
+               // will be filled with a repeated pattern of mem[src:src+k].
+               // We copy one instance of the pattern here, then repeat.
+               // Each time around this loop k will double.
+               k := dst - src
+               copy(mem[dst:dst+k], mem[src:src+k])
+               n -= k
+               dst += k
        }
-       return len(src)
 }
index a9281d446e9c407aeea97e710956aaf50720a123..2011b1547c934cccae2540cd378b600ce789a0e8 100644 (file)
@@ -30,10 +30,12 @@ func TestForwardCopy(t *testing.T) {
        }
        for _, tc := range testCases {
                b := []byte("0123456789")
-               dst := b[tc.dst0:tc.dst1]
-               src := b[tc.src0:tc.src1]
-               n := forwardCopy(dst, src)
-               got := string(dst[:n])
+               n := tc.dst1 - tc.dst0
+               if tc.src1-tc.src0 < n {
+                       n = tc.src1 - tc.src0
+               }
+               forwardCopy(b, tc.dst0, tc.src0, n)
+               got := string(b[tc.dst0 : tc.dst0+n])
                if got != tc.want {
                        t.Errorf("dst=b[%d:%d], src=b[%d:%d]: got %q, want %q",
                                tc.dst0, tc.dst1, tc.src0, tc.src1, got, tc.want)
index beca34b4d8ce0eb385aedf52b8cc03a85f727157..f529c9e7c232b467e93080ab1212ae4dca4348e1 100644 (file)
@@ -511,7 +511,7 @@ func (f *decompressor) copyHist() bool {
                if x := len(f.hist) - p; n > x {
                        n = x
                }
-               forwardCopy(f.hist[f.hp:f.hp+n], f.hist[p:p+n])
+               forwardCopy(f.hist[:], f.hp, p, n)
                p += n
                f.hp += n
                f.copyLen -= n