...
Run Format

Source file test/bench/garbage/parser.go

Documentation: test/bench/garbage

  // 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",
  }
  

View as plain text