1 回答

TA贡献1853条经验 获得超6个赞
并发不是并行。通道的这种特殊使用结果与仅从 返回值非常相似removeDuplicates
,只是两个 goroutine 需要协调它们对通道的使用会产生额外的开销。
具体来说:
循环的每次迭代都有自己的通道,每个通道只能容纳一个元素。
在所有语句都已执行之前,循环无法继续下一次迭代,包括对该语句的调用
log.Printf
阻塞,直到从通道接收到值。removeDuplicates
检测到实时时间已经过去了多少,而不是在解决问题上花费了多少时间。这是评论说它首先不是一个很好的基准的众多原因之一。
推测:在循环的前几次迭代中,goroutine 可能removeDuplicates
会初始化start
,然后将执行时间交给主 goroutine。然后 main goroutine 立即检查 mutex on c
,发现它还不能做任何事情,并返回给调度程序,所有这些检查和上下文切换增加了数千纳秒(关心这通常是微基准测试的味道)到goroutineremoveDuplicates
的实时执行。main
在几次迭代之后,某些东西(也许是 Go 运行时)发现了在返回之前永远无法取得进展的事实removeDuplicates
,并且避免了上下文切换。
我知道此时您对解释比建议更感兴趣,但如果我不指出比较 Go 和 Java 的基准已经存在,我会觉得很不负责任。即使您想自己编写,我也建议使用类似的方法:根据需要完成的任务定义基准程序,然后使用每种语言(或框架)中可用的最佳工具来完成工作具有良好的性能。
- 1 回答
- 0 关注
- 102 浏览
添加回答
举报