下面是主程代碼,這是詳細代碼
func main() {
//解析參數
filePath := flag.String("f", "", "文件路徑")
tplId := flag.String("t", "", "模版 ID")
flag.Parse()
//解析密鑰
pk, err := ParsePrivateKey()
check(err)
//讀取文件
start := time.Now()
csvFile, err := os.Open(*filePath)
check(err)
defer csvFile.Close()
csvReader := csv.NewReader(csvFile)
arr, err := csvReader.ReadAll()
fmt.Println(len(arr))
check(err)
paramsChan := make(chan string, 200)
//統計成功與失敗數量
var mutex = &sync.Mutex{}
successNum := 0
failNum := 0
var wg sync.WaitGroup
go func() {
for _, row := range arr {
wg.Add(1)
go func(row []string) { //通過添加顯式參數,確保當 go 語句執行時,使用當前 row 值(參考 5.6.1 內部匿名函數中獲取循環變量的問題)
defer wg.Done()
params, err := getQuery(row, *tplId, pk)
if err != nil {
fmt.Println(err)
}
paramsChan
}(row)
}
wg.Wait()
close(paramsChan) //安全關閉通道
}()
var wg2 sync.WaitGroup
limit := make(chan bool, 100)
for s := range paramsChan {
wg2.Add(1)
limit
go func(s string) {
defer wg2.Done()
res, err := sendMsg(s)
if err != nil {
fmt.Println(err)
mutex.Lock()
failNum++
mutex.Unlock()
}
if res {
mutex.Lock()
successNum++
mutex.Unlock()
} else {
mutex.Lock()
failNum++
mutex.Unlock()
}
}(s)
}
wg2.Wait()
fmt.Printf("發券成功:%d\n", successNum)
fmt.Printf("發券失敗:%d\n", failNum)
fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}
現在如果只整理請求參數,讀取 10W 行的 csv 文件,大概耗時 110-120S 左右,耗費內存在 900M 左右。如果加上發送請求的代碼,會因為內存消耗太大,直接被操作系統 KILL。
我用 PHP 開 4 個進程+guzzle 異步請求,處理完 10W 數據耗時在 110S 左右。
性能差這么多,這究竟是我代碼寫的太菜還是因為 PHP 是最好語言?(手動狗頭)