Skip to content

Commit

Permalink
http2/hpack: reduce memory for huffman decoding table
Browse files Browse the repository at this point in the history
Reduces process-wide heap (inuse_space) by 60kB by using a pointer to
a fixed-sized array instead of a slice of a fixed size.

Before:
119.44kB 23.43% 23.43%   147.88kB 29.01%  golang.org/x/net/http2/hpack.addDecoderNode

After:
 59.72kB 13.28% 39.85%    87.94kB 19.56%  golang.org/x/net/http2/hpack.addDecoderNode

(This is all work from an init func in http2/hpack)

Doesn't seem to affect runtime performance.

Measured with:

$ cat huffman_test.go
package main

import (
        "testing"

        _ "golang.org/x/net/http2"
        )

func TestMem(t *testing.T) {}

$ GODEBUG=memprofilerate=1 go test -memprofilerate=1 -memprofile=mem.prof -v .
=== RUN   TestMem
--- PASS: TestMem (0.00s)
PASS
ok      huffmem 0.052s

$ go tool pprof --inuse_space mem.prof

Change-Id: I5e56a5a2682f1063c955b342b37e97ca4c303dab
Reviewed-on: https://go-review.googlesource.com/127235
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
bradfitz committed Aug 1, 2018
1 parent 55471f4 commit 7368982
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
21 changes: 21 additions & 0 deletions hpack/hpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,27 @@ func TestHuffmanDecode(t *testing.T) {
}
}

func BenchmarkHuffmanDecode(b *testing.B) {
b.StopTimer()
enc, err := hex.DecodeString(strings.Replace("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07",
" ", "", -1))
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.StartTimer()
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
if _, err := HuffmanDecode(&buf, enc); err != nil {
b.Fatalf("decode error: %v", err)
}
if string(buf.Bytes()) != "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1" {
b.Fatalf("bogus output %q", buf.Bytes())
}
}
}

func TestAppendHuffmanString(t *testing.T) {
tests := []struct {
in, want string
Expand Down
4 changes: 2 additions & 2 deletions hpack/huffman.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {

type node struct {
// children is non-nil for internal nodes
children []*node
children *[256]*node

// The following are only valid if children is nil:
codeLen uint8 // number of bits that led to the output of sym
sym byte // output symbol
}

func newInternalNode() *node {
return &node{children: make([]*node, 256)}
return &node{children: new([256]*node)}
}

var rootHuffmanNode = newInternalNode()
Expand Down

0 comments on commit 7368982

Please sign in to comment.