
当切片规模较小(如百项以内)且单次处理耗时有限时,盲目并发收益甚微;但若需对每个元素独立执行 cpu 或 i/o 密集型操作,可通过 sync.waitgroup 协调 goroutines 实现真正的并行处理。
当切片规模较小(如百项以内)且单次处理耗时有限时,盲目并发收益甚微;但若需对每个元素独立执行 cpu 或 i/o 密集型操作,可通过 sync.waitgroup 协调 goroutines 实现真正的并行处理。
在 Go 中,对切片元素进行批量处理时,默认的顺序循环(for range)简单可靠,但并非唯一选择。若 cleanString 操作实际涉及较重计算(如 HTML 解析、正则匹配、网络请求等),或切片后续会显著扩大(数百至数千项),则可考虑并行化以提升吞吐量。
以下是一个安全、可复用的并行处理模板:
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
import (
"sync"
)
func parallelClean(results []SomeCustomStruct) {
var wg sync.WaitGroup
wg.Add(len(results))
for i := range results {
// 注意:捕获索引 i 的副本,避免闭包变量复用问题
go func(idx int) {
defer wg.Done()
results[idx].Body = cleanString(results[idx].Body)
}(i)
}
wg.Wait()
}
⚠️ 关键注意事项:
- 闭包陷阱:务必传递 i(而非 range 中的 index 变量本身)作为参数,否则所有 goroutine 可能读取到同一个迭代末尾值;
- 共享内存安全:本例中每个 goroutine 写入切片不同索引位置,无数据竞争;若需读写同一字段或全局状态,必须加锁(如 sync.Mutex)或改用通道通信;
- 开销权衡:启动 100 个 goroutine 的调度与同步成本可能抵消处理收益——建议对真实数据做基准测试(go test -bench);
- 错误处理缺失:当前示例未处理 cleanString 可能的 panic 或错误。生产环境应增加 recover 机制或返回 error 并集中收集;
- 更优替代方案:对于纯 CPU 密集型任务,runtime.GOMAXPROCS 默认已启用多核,配合 sync.Pool 复用中间对象(如 strings.Builder)往往比粗粒度 goroutine 更高效。
总结:小规模切片(≤100)通常无需并发;真正受益于并行的场景是单次处理延迟高(>1ms)、逻辑相互独立、且总数据量足以摊薄 goroutine 启动成本。始终以 profile 数据为决策依据,而非直觉。










