@
ensonmj 真相了,我把带 goroutine 的那个 LOOP 方法去掉,就符合预期了
@
janxin 下面是我的代码
```
package main
import (
"flag"
"os"
"runtime/pprof"
"log"
"fmt"
"runtime"
"bufio"
"sync"
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
var blockprofile = flag.String("blockprofile", "", "write block profile to `file`")
var mutexprofile = flag.String("mutexprofile", "", "write mutex profile to `file`")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
if *blockprofile != "" {
runtime.SetBlockProfileRate(10 * 1000)
defer writeProfTo("block", *blockprofile)
}
if *mutexprofile != "" {
runtime.SetMutexProfileFraction(2)
defer writeProfTo("mutex", *mutexprofile)
}
m := make(map[int]*TrieNode, 4)
for i := 0; i < 3; i++ {
m[i] = BuildTire()
//loop.Loop()
}
//for i := 1; i < 10; i++ {
// ctA()
//}
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
//runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f.Close()
}
}
func ctA() int64 {
return ctB()
}
func ctB() int64 {
var x int64 = 0
for i := 0; i < 1e9; i++ {
x = x + 1
}
return x + ctC() + ctD()
}
func ctC() int64 {
var x int64 = 0
for i := 0; i < 1e8; i++ {
x = x + 1
}
return x
}
func ctD() int64 {
var x int64 = 0
for i := 0; i < 5e8; i++ {
x = x + 1
}
return x
}
func writeProfTo(name, fn string) {
p := pprof.Lookup(name)
if p == nil {
fmt.Errorf("%s prof not found", name)
return
}
f, err := os.Create(fn)
if err != nil {
fmt.Errorf("%v", err.Error())
return
}
defer f.Close()
err = p.WriteTo(f, 0)
if err != nil {
fmt.Errorf("%v", err.Error())
return
}
}
type TrieNode struct {
Child *map[string]TrieNode
Exist bool
}
var mySlice []int
var sliceLock sync.RWMutex
func BuildTire() *TrieNode {
root := TrieNode{nil, false}
inFile, _ := os.Open("/Users/admin/stopwords.txt")
defer inFile.Close()
scanner := bufio.NewScanner(inFile)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
lineStr := scanner.Text()
root.addWord(lineStr)
Loop()
}
return &root
}
func Loop() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
for i := 0; i < 10; i++ {
sliceLock.Lock()
mySlice = append(mySlice, i)
sliceLock.Unlock()
}
wg.Done()
}()
}
wg.Wait()
}
func GetMySliceLen() int {
return len(mySlice)
}
func (n *TrieNode) addWord(words string) {
runes := []rune(words)
keyStr := string(runes[0])
var exist bool
var restStr string
if len(runes) == 1 {
exist = true
restStr = ""
} else {
exist = false
restStr = string(runes[1:])
}
if n.Child == nil {
tm := make(map[string]TrieNode)
n.Child = &tm
}
tmpMap := *n.Child
if _, ok := tmpMap[keyStr]; !ok {
tmpMap[keyStr] = TrieNode{nil, exist}
} else {
if exist {
//tmpMap[keyStr].Exist = exist
tm := tmpMap[keyStr]
tm.Exist = exist
tmpMap[keyStr] = tm
}
}
n.Child = &tmpMap
if len(restStr) > 0 {
tm := tmpMap[keyStr]
tm.addWord(restStr)
tmpMap[keyStr] = tm
}
}
```