Ich habe gerade erst angefangen zu lernen gehen auf Empfehlung eines Freundes. Bis jetzt, ich liebe es, aber ich schrieb (was ich dachte) wäre das perfekte Beispiel für die Kraft der leichten Nebenläufigkeit, und hatte ein überraschendes Ergebnis ... also vermute ich, dass ich etwas falsch mache, oder ich bin Missverständnis, wie teuer Göroutinen sind. Ich hoffe, dass einige Gopher hier Einblick geben können.Go Concurrency: Chudnovky Algorithmus, langsamer als Sync
Ich schrieb Chudnovsky-Algorithmus in Go mit beiden Göroutinen und einfache synchrone Ausführung. Ich nahm an, dass jede Berechnung unabhängig von den anderen zumindest zeitgleich schneller laufen würde.
Anmerkung: Ich bin diesen i7 auf einem fünften Generation laufen, also wenn goroutines auf Fäden gemultiplext werden, wie mir gesagt wurde, soll dies sowohl die gleichzeitige und parallel sein.
package main
import (
"fmt"
"math"
"strconv"
"time"
)
func main() {
var input string
var sum float64
var pi float64
c := make(chan float64)
fmt.Print("How many iterations? ")
fmt.Scanln(&input)
max,err := strconv.Atoi(input)
if err != nil {
panic("You did not enter a valid integer")
}
start := time.Now() //start timing execution of concurrent routine
for i := 0; i < max; i++ {
go chudnovskyConcurrent(i,c)
}
for i := 0; i < max; i++ {
sum += <-c
}
end := time.Now() //end of concurrent routine
fmt.Println("Duration of concurrent calculation: ",end.Sub(start))
pi = 1/(12*sum)
fmt.Println(pi)
start = time.Now() //start timing execution of syncronous routine
sum = 0
for i := 0; i < max; i++ {
sum += chudnovskySync(i)
}
end = time.Now() //end of syncronous routine
fmt.Println("Duration of synchronous calculation: ",end.Sub(start))
pi = 1/(12*sum)
fmt.Println(pi)
}
func chudnovskyConcurrent(i int, c chan<- float64) {
var numerator float64
var denominator float64
ifloat := float64(i)
iun := uint64(i)
numerator = math.Pow(-1, ifloat) * float64(factorial(6*iun)) * (545140134*ifloat+13591409)
denominator = float64(factorial(3*iun)) * math.Pow(float64(factorial(iun)),3) * math.Pow(math.Pow(640320,3),ifloat+0.5)
c <- numerator/denominator
}
func chudnovskySync(i int) (r float64) {
var numerator float64
var denominator float64
ifloat := float64(i)
iun := uint64(i)
numerator = math.Pow(-1, ifloat) * float64(factorial(6*iun)) * (545140134*ifloat+13591409)
denominator = float64(factorial(3*iun)) * math.Pow(float64(factorial(iun)),3) * math.Pow(math.Pow(640320,3),ifloat+0.5)
r = numerator/denominator
return
}
func factorial(n uint64) (res uint64) {
if (n > 0) {
res = n * factorial(n-1)
return res
}
return 1
}
Und hier sind meine Ergebnisse:
How many iterations? 20
Duration of concurrent calculation: 573.944µs
3.1415926535897936
Duration of synchronous calculation: 63.056µs
3.1415926535897936
goroutines sind billig, sie sind nicht frei. Was ist die Ausgabe des Befehls 'go version'? – peterSO
go version go1.6 linux/amd64 – Keozon
BUG ALERT: Ihr Beispiel, 20 Iterationen, überfließt Ihre Fakultätsfunktion. – peterSO