Skip to content

Instantly share code, notes, and snippets.

@tatocaster
Created May 21, 2020 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatocaster/ee58aed25dacc076428eedf7846865f9 to your computer and use it in GitHub Desktop.
Save tatocaster/ee58aed25dacc076428eedf7846865f9 to your computer and use it in GitHub Desktop.
concurrent calculation of factorial in golang
package main
import (
"fmt"
"math/big"
"runtime"
"time"
)
type computationRange struct {
start int64
end int64
}
var jobs []chan big.Int
var ranges chan []computationRange
func main() {
start := time.Now()
ranges = make(chan []computationRange)
go CalculateComputationRange(10000)
StartComputation()
result := CalculateFinalResult()
elapsed := time.Since(start)
fmt.Println("result: ", result)
fmt.Println("spent time in millis:", elapsed)
}
func CalculateComputationRange(factorialArgument int) {
var numberOfThreads int
if numberOfThreads = runtime.NumCPU(); factorialArgument < 20 {
numberOfThreads = 1
}
var computationRangeSize = factorialArgument / numberOfThreads
computationRanges := make([]computationRange, numberOfThreads)
var nextComputationRangeEnd = int64(factorialArgument)
for i := numberOfThreads - 1; i >= 0; i-- {
computationRanges[i] = computationRange{
start: 1 + nextComputationRangeEnd - int64(computationRangeSize),
end: nextComputationRangeEnd}
nextComputationRangeEnd = computationRanges[i].start - 1
}
ranges <- computationRanges
}
func StartComputation() {
computationRanges := <-ranges
for i := 0; i < len(computationRanges); i++ {
job := make(chan big.Int, 1)
jobs = append(jobs, job)
go startRangeComputation(job, computationRanges[i], i)
}
}
func startRangeComputation(job chan<- big.Int, computationRange computationRange, rangeIndex int) {
product := big.NewInt(1)
for i := computationRange.start; i <= computationRange.end; i++ {
product.Mul(product, big.NewInt(i))
}
job <- *product
}
func CalculateFinalResult() *big.Int {
result := big.NewInt(1)
for _, job := range jobs {
jobResult := <-job
close(job)
result.Mul(result, &jobResult)
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment