1
2
3
4
5
6
7 package main
8
9 import (
10 "flag"
11 "fmt"
12 "go/ast"
13 "go/parser"
14 "go/token"
15 "log"
16 "net/http"
17 _ "net/http/pprof"
18 "os"
19 "path"
20 "runtime"
21 "strings"
22 "time"
23 )
24
25 var serve = flag.String("serve", "", "serve http on this address at end")
26
27 func isGoFile(dir os.FileInfo) bool {
28 return !dir.IsDir() &&
29 !strings.HasPrefix(dir.Name(), ".") &&
30 path.Ext(dir.Name()) == ".go"
31 }
32
33 func isPkgFile(dir os.FileInfo) bool {
34 return isGoFile(dir) &&
35 !strings.HasSuffix(dir.Name(), "_test.go")
36 }
37
38 func pkgName(filename string) string {
39 file, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.PackageClauseOnly)
40 if err != nil || file == nil {
41 return ""
42 }
43 return file.Name.Name
44 }
45
46 func parseDir(dirpath string) map[string]*ast.Package {
47
48
49 _, pkgname := path.Split(dirpath)
50
51
52 filter := func(d os.FileInfo) bool {
53 if isPkgFile(d) {
54
55
56
57
58
59
60 name := pkgName(dirpath + "/" + d.Name())
61 return name == pkgname
62 }
63 return false
64 }
65
66
67 pkgs, err := parser.ParseDir(token.NewFileSet(), dirpath, filter, parser.ParseComments)
68 if err != nil {
69 println("parse", dirpath, err.Error())
70 panic("fail")
71 }
72 return pkgs
73 }
74
75 func main() {
76 st := new(runtime.MemStats)
77 packages = append(packages, packages...)
78 packages = append(packages, packages...)
79 n := flag.Int("n", 4, "iterations")
80 p := flag.Int("p", len(packages), "# of packages to keep in memory")
81 flag.BoolVar(&st.DebugGC, "d", st.DebugGC, "print GC debugging info (pause times)")
82 flag.Parse()
83
84 var lastParsed []map[string]*ast.Package
85 var t0 time.Time
86 var numGC uint32
87 var pauseTotalNs uint64
88 pkgroot := runtime.GOROOT() + "/src/"
89 for pass := 0; pass < 2; pass++ {
90
91
92
93
94 runtime.ReadMemStats(st)
95 numGC = st.NumGC
96 pauseTotalNs = st.PauseTotalNs
97 t0 = time.Now()
98
99 for i := 0; i < *n; i++ {
100 parsed := make([]map[string]*ast.Package, *p)
101 for j := range parsed {
102 parsed[j] = parseDir(pkgroot + packages[j%len(packages)])
103 }
104 if i+1 == *n && *serve != "" {
105 lastParsed = parsed
106 }
107 }
108 runtime.GC()
109 runtime.GC()
110 }
111 t1 := time.Now()
112
113 runtime.ReadMemStats(st)
114 st.NumGC -= numGC
115 st.PauseTotalNs -= pauseTotalNs
116 fmt.Printf("Alloc=%d/%d Heap=%d Mallocs=%d PauseTime=%.3f/%d = %.3f\n",
117 st.Alloc, st.TotalAlloc,
118 st.Sys,
119 st.Mallocs, float64(st.PauseTotalNs)/1e9,
120 st.NumGC, float64(st.PauseTotalNs)/1e9/float64(st.NumGC))
121
122
128
129 gcstats("BenchmarkParser", *n, t1.Sub(t0))
130
131 if *serve != "" {
132 log.Fatal(http.ListenAndServe(*serve, nil))
133 println(lastParsed)
134 }
135 }
136
137
138 var packages = []string{
139 "archive",
140 "archive/tar",
141 "archive/zip",
142 "bufio",
143 "builtin",
144 "bytes",
145 "compress",
146 "compress/bzip2",
147 "compress/flate",
148 "compress/gzip",
149 "compress/lzw",
150 "compress/zlib",
151 "container",
152 "container/heap",
153 "container/list",
154 "container/ring",
155 "crypto",
156 "crypto/aes",
157 "crypto/cipher",
158 "crypto/des",
159 "crypto/dsa",
160 "crypto/ecdsa",
161 "crypto/elliptic",
162 "crypto/hmac",
163 "crypto/md5",
164 "crypto/rand",
165 "crypto/rc4",
166 "crypto/rsa",
167 "crypto/sha1",
168 "crypto/sha256",
169 "crypto/sha512",
170 "crypto/subtle",
171 "crypto/tls",
172 "crypto/x509",
173 "crypto/x509/pkix",
174 "database",
175 "database/sql",
176 "database/sql/driver",
177 "debug",
178 "debug/dwarf",
179 "debug/elf",
180 "debug/gosym",
181 "debug/macho",
182 "debug/pe",
183 "encoding",
184 "encoding/ascii85",
185 "encoding/asn1",
186 "encoding/base32",
187 "encoding/base64",
188 "encoding/binary",
189 "encoding/csv",
190 "encoding/gob",
191 "encoding/hex",
192 "encoding/json",
193 "encoding/pem",
194 "encoding/xml",
195 "errors",
196 "expvar",
197 "flag",
198 "fmt",
199 "go",
200 "go/ast",
201 "go/build",
202 "go/doc",
203 "go/format",
204 "go/parser",
205 "go/printer",
206 "go/scanner",
207 "go/token",
208 "hash",
209 "hash/adler32",
210 "hash/crc32",
211 "hash/crc64",
212 "hash/fnv",
213 "html",
214 "html/template",
215 "image",
216 "image/color",
217 "image/draw",
218 "image/gif",
219 "image/jpeg",
220 "image/png",
221 "index",
222 "index/suffixarray",
223 "io",
224 "io/ioutil",
225 "log",
226 "log/syslog",
227 "math",
228 "math/big",
229 "math/cmplx",
230 "math/rand",
231 "mime",
232 "mime/multipart",
233 "net",
234 "net/http",
235 "net/http/cgi",
236 "net/http/cookiejar",
237 "net/http/fcgi",
238 "net/http/httptest",
239 "net/http/httputil",
240 "net/http/pprof",
241 "net/mail",
242 "net/rpc",
243 "net/rpc/jsonrpc",
244 "net/smtp",
245 "net/textproto",
246 "net/url",
247 "os",
248 "os/exec",
249 "os/signal",
250 "os/user",
251 "path",
252 "path/filepath",
253 "reflect",
254 "regexp",
255 "regexp/syntax",
256 "runtime",
257 "runtime/cgo",
258 "runtime/debug",
259 "runtime/pprof",
260 "runtime/race",
261 "sort",
262 "strconv",
263 "strings",
264 "sync",
265 "sync/atomic",
266 "syscall",
267 "testing",
268 "testing/iotest",
269 "testing/quick",
270 "text",
271 "text/scanner",
272 "text/tabwriter",
273 "text/template",
274 "text/template/parse",
275 "time",
276 "unicode",
277 "unicode/utf16",
278 "unicode/utf8",
279 "unsafe",
280 }
281
View as plain text