Golang多goroutine求解1000万和1亿以内的素数
使用单个goroutine求解1000万以内的素数。
package mainimport ("fmt""math""time"
)func IsPrime(n int) bool {if n <= 1 {return false}if n == 2 {return true}if n%2 == 0 {return false}sqrtN := int(math.Sqrt(float64(n)))for i := 3; i <= sqrtN; i += 2 {if n%i == 0 {return false}}return true
}
func main() {start := time.Now()for i := 0; i < 10000000; i++ {if IsPrime(i) {println(i)}}elapsed := time.Since(start).Seconds()fmt.Printf("end:%.3f", elapsed)
}
所需要的时间:38.332

2000个goroutine同时求解1000万以内的素数。
package mainimport ("fmt""math""time"
)func initChan(intchan chan int, num int) {for i := 0; i < num; i++ {intchan <- i}close(intchan)
}
func IsPrime(n int) bool {if n <= 1 {return false}if n == 2 {return true}if n%2 == 0 {return false}sqrtN := int(math.Sqrt(float64(n)))for i := 3; i <= sqrtN; i += 2 {if n%i == 0 {return false}}return true
}
func savePrime(intchan chan int, primechan chan int, exitchan chan bool) {for i := range intchan { //如果intchan没有关闭,那么就会永远阻塞if IsPrime(i) {primechan <- i}}exitchan <- true
}
func main() {start := time.Now()goNum := 2000primeNum := 10000000var intchan chan int = make(chan int, primeNum)var primechan chan int = make(chan int, primeNum)var exitchan chan bool = make(chan bool, goNum)go initChan(intchan, primeNum)for i := 0; i < goNum; i++ {go savePrime(intchan, primechan, exitchan)}go func() {for i := 0; i < goNum; i++ {<-exitchan}close(primechan) //执行完goNum个goroutine之后,不会再写入了,必须关闭}()for {v, ok := <-primechan //如果primechan不关闭,这里就会永远阻塞if !ok {break}println(v)}elapsed := time.Since(start).Seconds()fmt.Printf("end:%.3f", elapsed)
}
所需要的时间:26.374s。

可以发现当数据量较小的情况下,多goroutine的并发优势并没有比单goroutine有多少的提升。
当数据量变为1亿的时候,即使是先运行单goroutine的程序,后运行多goroutine的程序,多goroutine的程序的输出也慢慢的超过了单goroutine。
多goroutine已经打印到了

单goroutine还在

最后的时间差距也非常巨大:
多goroutine(10000):344.432s
多goroutine(1000000):282.058s
单goroutine:415.672s
