在这种情况下,Go语言中的通道是必需的吗?

huangapple go评论77阅读模式
英文:

Go : channel is necessary in this case?

问题

以下是翻译好的内容:

http://play.golang.org/p/Xn3Qw7xAi3

很难理解通道的意义。

这里有一个示例:

func main() {
  in := make(chan int)
  out := make(chan int)
  go QuickSort(in, out)

  for i := 0; i < 100; i++ {
    in <- rand.Intn(1000)
  }
  close(in)

  for i := range out {
    fmt.Println(i)
  }
}

这段代码创建了两个名为in和out的通道,并在一个goroutine中调用了QuickSort函数。

QuickSort函数如何接收in和out作为参数?它是否从下面这行代码接收数据?

  in <- rand.Intn(1000)

这种使用通道的方式是否最优?看起来非常简洁,可以动态地接收值...如果没有使用通道,只是普通排序会有什么不同?这种情况下是否更快?

英文:

http://play.golang.org/p/Xn3Qw7xAi3

It is hard to make sense of channel.

Here I have

func main() {
  in := make(chan int)
  out := make(chan int)
  go QuickSort(in, out)

  for i := 0; i &lt; 100; i++ {
    in &lt;- rand.Intn(1000)
  }
  close(in)

  for i := range out {
    fmt.Println(i)
  }
}

This makes two channels named in, out and goroutine the function Quicksort.

1.
How QuickSort take in and out as arguments? Does it receive from the line below?

  in &lt;- rand.Intn(1000)

2.
Is this case optimal using channel? It looks pretty neat receiving values dynamically... What would be different just sorting without channel? This case is faster?

答案1

得分: 2

我写了那个的原始版本!

我原始的写作回答了你的第二个问题,我想...

只是为了好玩 - 基于通道的快速排序。

有趣的是,你可以做一个快速排序,而不需要能够索引你的输入。它可能是O(n log n)的比较复杂度,但对于通道和Go协程来说,它是O(n)的,所以可能不是最高效的快速排序算法 在这种情况下,Go语言中的通道是必需的吗?

如果你给它排序好的输入,它的最坏情况复杂度是O(n²),所以不要这样做!

这只是一点儿好玩而已 - 但它使用了大量的通道和goroutine,这会使它比传统的快速排序算法更慢,占用更多的内存。

英文:

I wrote the original version of that!

My original write-up answers your second question I think...

> Just for fun - a channel based quicksort.
>
> Interesting that you can make a quicksort without being able to index
> your input. It may be O(n log n) for comparisons but it is O(n) for
> channels and go routines so perhaps not the most efficient quicksort
> ever 在这种情况下,Go语言中的通道是必需的吗?
>
> It also has the worst case complexity O(n²) if you feed it sorted
> input, so don't do that!

It is a bit of fun really - but it uses an awful lot of channels and goroutines which will make it slower and use more memory than a traditional quicksort.

答案2

得分: 1

  1. 快速排序函数的参数是如何传入和传出的?它是从下面的代码行接收的吗?

这段代码将100个随机数推送到名为"in"的通道中。之前你将这个通道的引用传递给了快速排序函数。这就好像我将一个线程安全的栈传递给一个函数,然后在调用者的上下文中将一个新元素推入该栈中。

for i := 0; i < 100; i++ {
  in <- rand.Intn(1000)
}
close(in)
  1. 这种情况下使用通道是否是最优的?动态接收值看起来很不错...如果没有使用通道,会有什么不同?这种情况下是否更快?

我认为这是一个很酷的玩具示例,展示了通道的灵活用法(以及流式排序)。在大多数常见情况下,通常更快、更容易的方法是将切片传递给sort.Sort函数进行排序。还值得注意的是,在大多数实际情况下,通过创建具有缓冲区的通道,可以获得更好的吞吐量,因为这将减少调度程序在goroutine之间切换的次数。通道的速度非常快,但仍然有开销,如果您实际上没有并行处理,那么这种开销对您没有任何好处。

如果您想要并行处理,请不要忘记将GOMAXPROCS设置为大于1,并使用带有缓冲区的通道。

英文:

> 1. How QuickSort take in and out as arguments? Does it receive from the
> line below?

This code pushes 100 random into into the channel called "in". You previously passed a reference to this channel to the quicksort function. This is the same idea as if I pass a function a thread-safe stack, and then from the callers context push a new element onto that stack.

  for i := 0; i &lt; 100; i++ {
    in &lt;- rand.Intn(1000)
  }
  close(in)

> 2. Is this case optimal using channel? It looks pretty neat receiving
> values dynamically... What would be different just sorting without
> channel? This case is faster?

I would consider this a cool toy example of how flexibly channels can be used (and a streaming sort). In most common cases, it is usually going to be much faster/easier to take a slice and call sort.Sort on it. Its also worth noting in most real world cases you will get better throughput by creating a channel with a buffer, as this will reduce the scheduler switching between goroutines. Channels are very fast, but they still have overhead and if you are not actually processing in parallel that overhead isn't buying you anything.

If you want to be processing in parallel don't forgot to set GOMAXPROCS > 1 and use buffered channels.

答案3

得分: -1

问题1的答案是肯定的。在示例中,QuickSort函数期望两个通道作为参数,一个用于读取整数,一个用于在排序后写入整数。这与在Unix命令行上使用stdin和stdout进行排序非常相似。

至于问题2的答案,这只是使用Go通道和Go协程解决标准问题的一个示例。只有在等待排序返回时有其他工作要做时,才会更快。

这段代码中真正可能加速的地方是在QuickSort函数内部使用通道和Go协程。如果底层硬件具有足够的核心来允许多线程程序,那么这可能比单线程版本快得多。

使用Go通道和线程的目的是让您轻松利用底层硬件,而不必编写多线程代码的困难。与此版本的基于pthread的快速排序代码进行比较,看看它与Go代码的区别。

http://sc12.supercomputing.org/hpceducator/PythonForParallelism/codes/parallelQuicksort.c

英文:

The answer to question 1 is yes. The QuickSort in the example expects two channels as arguements, one to read ints from and one to write ints to after they are sorted. It's very similar to using sort on the unix command line with stdin and stdout.

As to the answer to question 2, this is just an example of using Go Channels and go routines to solve a standard problem. It would only be faster if you had some other work to do while waiting for the sort to return.

The real speed up possible in this code is the use of channels and goroutines inside the QuickSort function. If your underlying hardware has sufficient cores to
allow you to multi-thread the program this could be significantly faster than a single threaded version.

The point of go channels and threads is to allow you to easily take advantage of the underlying hardware w/o the difficulties of writing threaded code. For comparision look at this version of a pthread based quicksort and compare it to the go code.

http://sc12.supercomputing.org/hpceducator/PythonForParallelism/codes/parallelQuicksort.c

huangapple
  • 本文由 发表于 2013年11月12日 03:19:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/19914133.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定