github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/utils/benchcomp/main.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "debug/elf" 6 "debug/macho" 7 "fmt" 8 "os" 9 "path/filepath" 10 "sort" 11 "strconv" 12 "strings" 13 ) 14 15 func symsizes(path string) map[string]float64 { 16 m := make(map[string]float64) 17 f, err := elf.Open(path) 18 if err != nil { 19 panic(err.Error()) 20 } 21 syms, err := f.Symbols() 22 if err != nil { 23 panic(err.Error()) 24 } 25 for _, sym := range syms { 26 if sym.Section < elf.SectionIndex(len(f.Sections)) && strings.HasPrefix(f.Sections[sym.Section].Name, ".text") { 27 m[sym.Name] = float64(sym.Size) 28 } 29 } 30 return m 31 } 32 33 type bySectionThenOffset []macho.Symbol 34 35 func (syms bySectionThenOffset) Len() int { 36 return len(syms) 37 } 38 39 func (syms bySectionThenOffset) Less(i, j int) bool { 40 if syms[i].Sect < syms[j].Sect { 41 return true 42 } 43 if syms[i].Sect > syms[j].Sect { 44 return false 45 } 46 return syms[i].Value < syms[j].Value 47 } 48 49 func (syms bySectionThenOffset) Swap(i, j int) { 50 syms[i], syms[j] = syms[j], syms[i] 51 } 52 53 func macho_symsizes(path string) map[string]float64 { 54 m := make(map[string]float64) 55 f, err := macho.Open(path) 56 if err != nil { 57 panic(err.Error()) 58 } 59 syms := make([]macho.Symbol, len(f.Symtab.Syms)) 60 copy(syms, f.Symtab.Syms) 61 sort.Sort(bySectionThenOffset(syms)) 62 for i, sym := range syms { 63 if sym.Sect == 0 { 64 continue 65 } 66 var nextOffset uint64 67 if i == len(syms)-1 || syms[i+1].Sect != sym.Sect { 68 nextOffset = f.Sections[sym.Sect-1].Size 69 } else { 70 nextOffset = syms[i+1].Value 71 } 72 m[sym.Name] = float64(nextOffset - sym.Value) 73 } 74 return m 75 } 76 77 func benchnums(path, stat string) map[string]float64 { 78 m := make(map[string]float64) 79 80 fh, err := os.Open(path) 81 if err != nil { 82 panic(err.Error()) 83 } 84 85 scanner := bufio.NewScanner(fh) 86 for scanner.Scan() { 87 elems := strings.Split(scanner.Text(), "\t") 88 if !strings.HasPrefix(elems[0], "Benchmark") || len(elems) < 3 { 89 continue 90 } 91 var s string 92 for _, elem := range elems[2:] { 93 selems := strings.Split(strings.TrimSpace(elem), " ") 94 if selems[1] == stat { 95 s = selems[0] 96 } 97 } 98 if s != "" { 99 ns, err := strconv.ParseFloat(s, 64) 100 if err != nil { 101 panic(scanner.Text() + " ---- " + err.Error()) 102 } 103 m[elems[0]] = ns 104 } 105 } 106 107 if err := scanner.Err(); err != nil { 108 panic(err) 109 } 110 111 return m 112 } 113 114 func ninja_logs(path string) map[string]float64 { 115 m := make(map[string]float64) 116 117 fh, err := os.Open(path) 118 if err != nil { 119 panic(err.Error()) 120 } 121 122 scanner := bufio.NewScanner(fh) 123 for scanner.Scan() { 124 elems := strings.Split(scanner.Text(), "\t") 125 if len(elems) < 4 { 126 continue 127 } 128 begin, err := strconv.ParseInt(elems[0], 10, 64) 129 if err != nil { 130 continue 131 } 132 end, err := strconv.ParseInt(elems[1], 10, 64) 133 if err != nil { 134 panic(err.Error()) 135 } 136 m[elems[3]] = float64(end-begin) 137 } 138 139 return m 140 } 141 142 func filesizes(root string) map[string]float64 { 143 m := make(map[string]float64) 144 145 err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { 146 if info.Mode().IsRegular() { 147 m[path[len(root):]] = float64(info.Size()) 148 } 149 return nil 150 }) 151 if err != nil { 152 panic(err.Error()) 153 } 154 155 return m 156 } 157 158 func main() { 159 var cmp func(string) map[string]float64 160 switch os.Args[1] { 161 case "symsizes": 162 cmp = symsizes 163 164 case "macho_symsizes": 165 cmp = macho_symsizes 166 167 case "benchns": 168 cmp = func(path string) map[string]float64 { 169 return benchnums(path, "ns/op") 170 } 171 172 case "benchallocs": 173 cmp = func(path string) map[string]float64 { 174 return benchnums(path, "allocs/op") 175 } 176 177 case "ninja_logs": 178 cmp = ninja_logs 179 180 case "filesizes": 181 cmp = filesizes 182 } 183 184 syms1 := cmp(os.Args[2]) 185 syms2 := cmp(os.Args[3]) 186 187 for n, z1 := range syms1 { 188 if z2, ok := syms2[n]; ok && z2 != 0 { 189 fmt.Printf("%s %f %f %f\n", n, z1, z2, z1/z2) 190 } 191 } 192 }