并发与同步[封闭]的性能比较

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发与同步[封闭]的性能比较相关的知识,希望对你有一定的参考价值。

我试图在Go中测量并发的性能,但得到了意想不到的结果,以下是我写的两个程序,它们给出了相同的结果

第一个节目

package main

import (
  "fmt"
  "time"
)

func looper(n int,c chan int) {
  sum := 0
  for i :=1 ;i < n; i++{
    sum = sum + i
  }
  c <- sum
}

func main() {
  start := time.Now()
  n := 10000000
  c := make(chan int)
  go looper(n, c)
  go looper(n, c)
  go looper(n, c)
  go looper(n, c)
  <- c
  <- c
  <- c
  <- c
  end := time.Now()
  fmt.Printf("took %v", end.Sub(start))
}

第二程序:

package main

import (
  "fmt"
  "time"
)

func looper(n int) (sum int) {
  for i :=1 ;i < n; i++{
    sum = sum + i
  }
  return sum
}

func main() {
  start := time.Now()
  n := 10000000
  looper(n)
  looper(n)
  looper(n)
  looper(n)
  end := time.Now()
  fmt.Printf("took %v", end.Sub(start))
}

但第一程序的运行时间比第二程序的运行时间要长。我的预期恰恰相反,为什么第二个程序比第一个程序快?为什么第二个程序比第一个程序快?

答案

在线代码执行平台不能用于性能测试(特别是涉及到并发时),因为1)你无法知道他们的设置是什么,2)他们很可能严重限制了可用的核心数量。

你也应该使用 基准,它们会比自己计算时间更可靠。

也就是说,你的例子没有错,在真实的环境中,它们会产生预期的结果。例如,如果我改变 n10000000000 并在我的机器上运行这两个测试,我得到了以下结果。

$ go build test1.go && time ./test1
took 2.631567986s
real    0m2.633s
user    0m10.014s
sys     0m0.016s

$ go build test2.go && time ./test2 
took 9.585642986s
real    0m9.587s
user    0m9.586s
sys     0m0.008s

请注意,他们花费了大约相同的时间 user 的时间。这是因为第一个程序使用了4个核心。但由于它的并发性,使得它只需要2.6s的 real 时间。

现在,如果我用原来的 n := 10000000,我获得。

$ go build test1.go && time ./test1
took 5.167403ms
real    0m0.006s
user    0m0.017s
sys     0m0.000s

$ go build test2.go && time ./test2 
took 10.059712ms
real    0m0.011s
user    0m0.012s
sys     0m0.000s

结果太接近了,无法判断(特别是当只运行一次时)。这是因为所做的工作与设置四个goroutine的成本相比太便宜了。

以上是关于并发与同步[封闭]的性能比较的主要内容,如果未能解决你的问题,请参考以下文章

Atitit.并发编程原理与概论 attilax总结

操作系统学习---进程管理

操作系统原理-进程线程模型并发与同步

Java并发编程与高并发解决方案

进程互斥与同步

操作系统(二 )| 进程(概念特征状态进程控制进程同步机制信号量应用同步机制遵循规则程序执行特点线程引入目的与进程的区别)