- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
比如说,我们有三种方法来实现“扇入”行为
func MakeChannel(tries int) chan int {
ch := make(chan int)
go func() {
for i := 0; i < tries; i++ {
ch <- i
}
close(ch)
}()
return ch
}
func MergeByReflection(channels ...chan int) chan int {
length := len(channels)
out := make(chan int)
cases := make([]reflect.SelectCase, length)
for i, ch := range channels {
cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
go func() {
for length > 0 {
i, line, opened := reflect.Select(cases)
if !opened {
cases[i].Chan = reflect.ValueOf(nil)
length -= 1
} else {
out <- int(line.Int())
}
}
close(out)
}()
return out
}
func MergeByCode(channels ...chan int) chan int {
length := len(channels)
out := make(chan int)
go func() {
var i int
var ok bool
for length > 0 {
select {
case i, ok = <-channels[0]:
out <- i
if !ok {
channels[0] = nil
length -= 1
}
case i, ok = <-channels[1]:
out <- i
if !ok {
channels[1] = nil
length -= 1
}
case i, ok = <-channels[2]:
out <- i
if !ok {
channels[2] = nil
length -= 1
}
case i, ok = <-channels[3]:
out <- i
if !ok {
channels[3] = nil
length -= 1
}
case i, ok = <-channels[4]:
out <- i
if !ok {
channels[4] = nil
length -= 1
}
}
}
close(out)
}()
return out
}
func MergeByGoRoutines(channels ...chan int) chan int {
var group sync.WaitGroup
out := make(chan int)
for _, ch := range channels {
go func(ch chan int) {
for i := range ch {
out <- i
}
group.Done()
}(ch)
}
group.Add(len(channels))
go func() {
group.Wait()
close(out)
}()
return out
}
type MergeFn func(...chan int) chan int
func main() {
length := 5
tries := 1000000
channels := make([]chan int, length)
fns := []MergeFn{MergeByReflection, MergeByCode, MergeByGoRoutines}
for _, fn := range fns {
sum := 0
t := time.Now()
for i := 0; i < length; i++ {
channels[i] = MakeChannel(tries)
}
for i := range fn(channels...) {
sum += i
}
fmt.Println(time.Since(t))
fmt.Println(sum)
}
}
结果是(在 1 个 CPU 下,我使用了 runtime.GOMAXPROCS(1)):
19.869s(通过反射合并)
2499997500000
8.483s (MergeByCode)
2499997500000
4.977s(MergeByGoRoutines)
2499997500000
结果是(在 2 个 CPU 下,我使用了 runtime.GOMAXPROCS(2)):
44.94s
2499997500000
10.853s
2499997500000
3.728s
2499997500000
最佳答案
这是一个初步的评论。您示例中的 channel 都是无缓冲的,这意味着它们可能会在放置或获取时间时阻塞。
在这个例子中,除了 channel 管理,几乎没有其他处理。因此,性能主要由同步原语决定。实际上,可以并行化的代码非常少。
在 MergeByReflection 和 MergeByCode 函数中,select 用于监听多个输入 channel ,但没有采取任何措施来考虑输出 channel (因此可能会阻塞,而某些事件可能在其中一个输入 channel 上可用) .
在 MergeByGoRoutines 函数中,这种情况不会发生:当输出 channel 阻塞时,它不会阻止另一个输入 channel 被另一个 goroutine 读取。因此,运行时有更好的机会并行化 goroutine,并减少对输入 channel 的争用。
MergeByReflection 代码是最慢的,因为它有反射的开销,几乎没有什么可以并行化。
MergeByGoRoutines 函数是最快的,因为它减少了争用(需要较少的同步),并且因为输出争用对输入性能的影响较小。因此,在使用多核运行时(与其他两种方法相反),它可以从小的改进中获益。
MergeByReflection 和 MergeByCode 的同步事件太多,在多个内核上运行会对性能产生负面影响。不过,您可以通过使用缓冲 channel 获得不同的性能。
关于go - "fan in"- 一种 "fan out"行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29827896/
比如说,我们有三种方法来实现“扇入”行为 func MakeChannel(tries int) chan int { ch := make(chan int) go func() {
我已经安装了 NDepend(14 天试用版)作为 Visual Studio 2015 扩展,现在可以使用了。 我想在我的解决方案中获得某些类的一些指标: 标识符的长度 扇入/扇出 类的加权方法 类
我计划将 Elasticsearch 用于一种社交网络平台,用户可以在其中发布“更新”,与其他用户成为 friend 并关注他们 friend 的提要。基本且可能是最常见的查询将是 “获取我关注的 f
进程文件: fan or fan.exe 进程名称: Fan 进程类别:存在安全风险的进程 英文描述: fan.exe is a process from Dell. It allows t
Argo 允许基于先前步骤的输出动态生成并行工作流步骤。 此处提供了此动态工作流生成的示例:https://github.com/argoproj/argo-workflows/blob/master
一直在尝试解决这个问题,但被难住了! 我想用 Jquery/CSS 创建一个动画,其中一堆图像旋转并创建一个圆弧。我认为最简单的方法是堆叠它们,然后从中心旋转它们,如下图所示。 我希望所有四张图片(只
我需要用户能够成为其他用户的粉丝。我应该如何设计/设置它? 我需要能够查看用户粉丝的详细信息。 例如。我有用户:Foo。 Foo 有 3 个粉丝。我希望能够找到 Foo 粉丝的名字。因此: foo =
我正在使用 facebook 的 javascript sdk 构建扇门。我想确定用户是否“喜欢”我的页面,以便我可以显示/Conceal 内容。目前,如果我使用 javascript sdk,系统会
我正在使用 Cesium 并希望在视觉上表示相同的两个实体之间的多条折线。例如,从实体 A 到实体 B 的绿色多段线,以及从实体 A 到实体 B 的蓝色多段线。我希望它们不要重叠或混合,所以我想象随着
我使用 js sdk 毫无问题地获取我的 friend 列表。我得到的列表来 self 的 facebook 个人页面 (Tony Easterbird) 我还有一个扇形页面,叫做 Katahdin
我正在调查 Firebase 数据库 sample对于安卓并意识到它以下列方式存储其数据: 我不太熟悉 NoSQL 技术并试图理解为什么我们必须坚持每个 post实体两次 - 在 posts和 use
我们是 Azure 消息服务和功能的新手,我们了解了不同消息服务的基本概念,例如存储队列、服务总线队列、服务总线主题和事件中心,我们还阅读了 fan-out pattern由微软开发,但其工作方式更像
我必须对项目列表运行一个函数。我正在使用 Azure Durable Functions,并且可以使用它们的 fan out/fan in 并行运行这些项目。策略。 但是,我想知道这样做与在单个 Ac
我们是 Azure 消息服务和功能的新手,我们了解了不同消息服务的基本概念,例如存储队列、服务总线队列、服务总线主题和事件中心,我们还阅读了 fan-out pattern由微软开发,但其工作方式更像
我必须对项目列表运行一个函数。我正在使用 Azure Durable Functions,并且可以使用它们的 fan out/fan in 并行运行这些项目。策略。 但是,我想知道这样做与在单个 Ac
我试图实现一个示例 Go 代码,用于使用从 go 例程返回的 channel ,而 main 函数中没有任何“读取 block ”。在这里,一个 fanIn 函数接受来自其他两个例程的 channel
嗨,我正在为我的新树莓派 4 戴上 POE-FAN 帽子而苦苦挣扎。 使用官方 POE-HAT 安装了几个 Pi:https://www.raspberrypi.org/products/poe-ha
我正在使用顶点数组制作一些相对简单的形状,并且取得了一些不错的进展,但现在我想绘制 2 个(或更多)三角形扇形对象。有没有办法只打一个电话到gl.glDrawArrays(GL.GL_TRIANGLE
我想获得喜欢某个页面或它的粉丝的用户列表。 FB API 文档指出,您只能使用社交图谱获取特定页面的粉丝数,而不能获取粉丝列表。 此处讨论Retrieve Facebook Fan Names建议可以
我的问题是:如何使用 D3DPT_TRIANGLEFAN 绘制正确的金字塔(三角形四边形金字塔)? 我用作积分: CUSTOMVERTEX vertices[] = { { 0.0f, 3.
我是一名优秀的程序员,十分优秀!