golang channels vs. routine spawn for performance
golang channels vs. routine spawn for performance
我很好奇是否有人分析过这两种范例之间的性能差异。
有一个侦听器 goroutine(可能有几个)侦听套接字并生成一个新的 goroutine 来处理该信息并将其发送到它必须去的任何地方。发送命令后,例程将完成并被销毁。每个请求都会创建一个例程,然后在完成时销毁它。
有一个侦听器 goroutine(可能有几个)侦听套接字并将数据传递到通道。许多 goroutines 阻塞在通道接收上,并轮流从通道中取出东西并处理它们。完成后,例程将在通道上等待以获取更多信息。在这个范例中,例程永远不会被破坏。几个主例程在通道上接收套接字信息,其他例程在通道上等待处理信息。套路是不会被破坏的。
我的问题是对于一个在接收中接收大量小信息的系统(每条消息 0.5-1.5kb)但是有很多消息同时进入(大容量,小尺寸)什么范例有利于速度和处理。坐着一堆例程并使用频道将它们分散到一堆听力例程中?或者,为每个请求创建路由并在每个请求后结束该例程?
即使是最基本的意识形态和猜想也很酷。
谢谢。
一般来说,我倾向于发现产生无数例程而不重新使用它们是一种浪费:即使 goroutines 很便宜,它们也不是免费的,这意味着调度成本。
现在,这两种方法在高负载下都有缺点:产生例程会消耗您的内存、调度,并且可能会使您的程序停止运行,而使用通道时,您的请求将挂起,直到前一个请求被处理。
我通常的做法是做一个基于批处理的流水线(灵感来自优秀的Go Concurrency Patterns: Pipelines and cancellations博客post):
- 监听器在通道中发送请求
- 一个聚合例程将请求放入缓冲区
- N 个处理例程在空闲时请求缓冲区块
这样您就可以精确地控制流水线的流程和行为,同时保持多个工作者的优势。您可以通过在缓冲区超过限制大小时丢弃传入请求、产生或杀死新工作人员以适应负载等来轻松实现溢出机制。
我很好奇是否有人分析过这两种范例之间的性能差异。
有一个侦听器 goroutine(可能有几个)侦听套接字并生成一个新的 goroutine 来处理该信息并将其发送到它必须去的任何地方。发送命令后,例程将完成并被销毁。每个请求都会创建一个例程,然后在完成时销毁它。
有一个侦听器 goroutine(可能有几个)侦听套接字并将数据传递到通道。许多 goroutines 阻塞在通道接收上,并轮流从通道中取出东西并处理它们。完成后,例程将在通道上等待以获取更多信息。在这个范例中,例程永远不会被破坏。几个主例程在通道上接收套接字信息,其他例程在通道上等待处理信息。套路是不会被破坏的。
我的问题是对于一个在接收中接收大量小信息的系统(每条消息 0.5-1.5kb)但是有很多消息同时进入(大容量,小尺寸)什么范例有利于速度和处理。坐着一堆例程并使用频道将它们分散到一堆听力例程中?或者,为每个请求创建路由并在每个请求后结束该例程?
即使是最基本的意识形态和猜想也很酷。
谢谢。
一般来说,我倾向于发现产生无数例程而不重新使用它们是一种浪费:即使 goroutines 很便宜,它们也不是免费的,这意味着调度成本。
现在,这两种方法在高负载下都有缺点:产生例程会消耗您的内存、调度,并且可能会使您的程序停止运行,而使用通道时,您的请求将挂起,直到前一个请求被处理。
我通常的做法是做一个基于批处理的流水线(灵感来自优秀的Go Concurrency Patterns: Pipelines and cancellations博客post):
- 监听器在通道中发送请求
- 一个聚合例程将请求放入缓冲区
- N 个处理例程在空闲时请求缓冲区块
这样您就可以精确地控制流水线的流程和行为,同时保持多个工作者的优势。您可以通过在缓冲区超过限制大小时丢弃传入请求、产生或杀死新工作人员以适应负载等来轻松实现溢出机制。