下面是主程代码,这是详细代码
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 <- params
}(row)
}
wg.Wait()
close(paramsChan) //安全关闭通道
}()
var wg2 sync.WaitGroup
limit := make(chan bool, 100)
for s := range paramsChan {
wg2.Add(1)
limit <- true
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()
}
<-limit
}(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 是最好语言?(手动狗头)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.