diff options
Diffstat (limited to 'test/bench/garbage/parser.go')
-rw-r--r-- | test/bench/garbage/parser.go | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/test/bench/garbage/parser.go b/test/bench/garbage/parser.go new file mode 100644 index 0000000..817afa9 --- /dev/null +++ b/test/bench/garbage/parser.go @@ -0,0 +1,280 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Garbage collection benchmark: parse Go packages repeatedly. + +package main + +import ( + "flag" + "fmt" + "go/ast" + "go/parser" + "go/token" + "log" + "net/http" + _ "net/http/pprof" + "os" + "path" + "runtime" + "strings" + "time" +) + +var serve = flag.String("serve", "", "serve http on this address at end") + +func isGoFile(dir os.FileInfo) bool { + return !dir.IsDir() && + !strings.HasPrefix(dir.Name(), ".") && // ignore .files + path.Ext(dir.Name()) == ".go" +} + +func isPkgFile(dir os.FileInfo) bool { + return isGoFile(dir) && + !strings.HasSuffix(dir.Name(), "_test.go") // ignore test files +} + +func pkgName(filename string) string { + file, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.PackageClauseOnly) + if err != nil || file == nil { + return "" + } + return file.Name.Name +} + +func parseDir(dirpath string) map[string]*ast.Package { + // the package name is the directory name within its parent + // (use dirname instead of path because dirname is clean; i.e. has no trailing '/') + _, pkgname := path.Split(dirpath) + + // filter function to select the desired .go files + filter := func(d os.FileInfo) bool { + if isPkgFile(d) { + // Some directories contain main packages: Only accept + // files that belong to the expected package so that + // parser.ParsePackage doesn't return "multiple packages + // found" errors. + // Additionally, accept the special package name + // fakePkgName if we are looking at cmd documentation. + name := pkgName(dirpath + "/" + d.Name()) + return name == pkgname + } + return false + } + + // get package AST + pkgs, err := parser.ParseDir(token.NewFileSet(), dirpath, filter, parser.ParseComments) + if err != nil { + println("parse", dirpath, err.Error()) + panic("fail") + } + return pkgs +} + +func main() { + st := new(runtime.MemStats) + packages = append(packages, packages...) + packages = append(packages, packages...) + n := flag.Int("n", 4, "iterations") + p := flag.Int("p", len(packages), "# of packages to keep in memory") + flag.BoolVar(&st.DebugGC, "d", st.DebugGC, "print GC debugging info (pause times)") + flag.Parse() + + var lastParsed []map[string]*ast.Package + var t0 time.Time + var numGC uint32 + var pauseTotalNs uint64 + pkgroot := runtime.GOROOT() + "/src/" + for pass := 0; pass < 2; pass++ { + // Once the heap is grown to full size, reset counters. + // This hides the start-up pauses, which are much smaller + // than the normal pauses and would otherwise make + // the average look much better than it actually is. + runtime.ReadMemStats(st) + numGC = st.NumGC + pauseTotalNs = st.PauseTotalNs + t0 = time.Now() + + for i := 0; i < *n; i++ { + parsed := make([]map[string]*ast.Package, *p) + for j := range parsed { + parsed[j] = parseDir(pkgroot + packages[j%len(packages)]) + } + if i+1 == *n && *serve != "" { + lastParsed = parsed + } + } + runtime.GC() + runtime.GC() + } + t1 := time.Now() + + runtime.ReadMemStats(st) + st.NumGC -= numGC + st.PauseTotalNs -= pauseTotalNs + fmt.Printf("Alloc=%d/%d Heap=%d Mallocs=%d PauseTime=%.3f/%d = %.3f\n", + st.Alloc, st.TotalAlloc, + st.Sys, + st.Mallocs, float64(st.PauseTotalNs)/1e9, + st.NumGC, float64(st.PauseTotalNs)/1e9/float64(st.NumGC)) + + /* + fmt.Printf("%10s %10s %10s\n", "size", "#alloc", "#free") + for _, s := range st.BySize { + fmt.Printf("%10d %10d %10d\n", s.Size, s.Mallocs, s.Frees) + } + */ + // Standard gotest benchmark output, collected by build dashboard. + gcstats("BenchmarkParser", *n, t1.Sub(t0)) + + if *serve != "" { + log.Fatal(http.ListenAndServe(*serve, nil)) + println(lastParsed) + } +} + +// find . -type d -not -path "./exp" -not -path "./exp/*" -printf "\t\"%p\",\n" | sort | sed "s/\.\///" | grep -v testdata +var packages = []string{ + "archive", + "archive/tar", + "archive/zip", + "bufio", + "builtin", + "bytes", + "compress", + "compress/bzip2", + "compress/flate", + "compress/gzip", + "compress/lzw", + "compress/zlib", + "container", + "container/heap", + "container/list", + "container/ring", + "crypto", + "crypto/aes", + "crypto/cipher", + "crypto/des", + "crypto/dsa", + "crypto/ecdsa", + "crypto/elliptic", + "crypto/hmac", + "crypto/md5", + "crypto/rand", + "crypto/rc4", + "crypto/rsa", + "crypto/sha1", + "crypto/sha256", + "crypto/sha512", + "crypto/subtle", + "crypto/tls", + "crypto/x509", + "crypto/x509/pkix", + "database", + "database/sql", + "database/sql/driver", + "debug", + "debug/dwarf", + "debug/elf", + "debug/gosym", + "debug/macho", + "debug/pe", + "encoding", + "encoding/ascii85", + "encoding/asn1", + "encoding/base32", + "encoding/base64", + "encoding/binary", + "encoding/csv", + "encoding/gob", + "encoding/hex", + "encoding/json", + "encoding/pem", + "encoding/xml", + "errors", + "expvar", + "flag", + "fmt", + "go", + "go/ast", + "go/build", + "go/doc", + "go/format", + "go/parser", + "go/printer", + "go/scanner", + "go/token", + "hash", + "hash/adler32", + "hash/crc32", + "hash/crc64", + "hash/fnv", + "html", + "html/template", + "image", + "image/color", + "image/draw", + "image/gif", + "image/jpeg", + "image/png", + "index", + "index/suffixarray", + "io", + "io/ioutil", + "log", + "log/syslog", + "math", + "math/big", + "math/cmplx", + "math/rand", + "mime", + "mime/multipart", + "net", + "net/http", + "net/http/cgi", + "net/http/cookiejar", + "net/http/fcgi", + "net/http/httptest", + "net/http/httputil", + "net/http/pprof", + "net/mail", + "net/rpc", + "net/rpc/jsonrpc", + "net/smtp", + "net/textproto", + "net/url", + "os", + "os/exec", + "os/signal", + "os/user", + "path", + "path/filepath", + "reflect", + "regexp", + "regexp/syntax", + "runtime", + "runtime/cgo", + "runtime/debug", + "runtime/pprof", + "runtime/race", + "sort", + "strconv", + "strings", + "sync", + "sync/atomic", + "syscall", + "testing", + "testing/iotest", + "testing/quick", + "text", + "text/scanner", + "text/tabwriter", + "text/template", + "text/template/parse", + "time", + "unicode", + "unicode/utf16", + "unicode/utf8", + "unsafe", +} |