I m trying to use the go tool trace. My code is
package main
import (
"flag"
"fmt"
"math"
"net/http"
"os"
"runtime"
"runtime/trace"
"time"
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
primesInRangeParallel(10, 64)
fmt.Fprintf(w, "hello world, I'm running on %s with an %s CPU ", runtime.GOOS, runtime.GOARCH)
}
func main() {
flag.Parse()
f, errs := os.Create(time.Now().Format("2006-01-02T150405.out"))
if errs != nil {
panic(errs)
}
if err := trace.Start(f); err != nil {
panic(err)
}
defer f.Close()
defer trace.Stop()
http.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", nil)
}
// We will use this struct to communicate results via a channel
type PrimeResult struct {
number int64 // A number
prime bool // Is prime or not
}
/**
* A function to return a prime calculation over a channel. This way
* we don't need to have 2 versions of isPrime function, one for
* sequential calculations and another for paralel
*/
func isPrimeAsync(number int64, channel chan PrimeResult) {
result := new(PrimeResult)
result.number = number
result.prime = isPrime(number)
channel <- *result
}
/**
* Accepts a range of integers [min, max] and a channel and it executes
* in PARALEL the processes that check if a number is prime or not.
*
* This function does nothing with the result. In another point, somebody
* will have to read the channel and process the results
*/
func firePrimeCalculations(min int64, max int64, channel chan PrimeResult) {
var i int64
for i = min; i <= max; i++ {
go isPrimeAsync(i, channel)
}
}
/**
* Accepts a range of integers [min, max] and
* returns an array with all the prime numbers in this range.
*
* Execution is done in paralel. First it fires all the
* processes that check for a prime number. These processes
* will write the result in a channel.
*
* We will receive the results over this channel creating the
* list of prime numbers and returning it
*
*/
func primesInRangeParallel(min int64, max int64) []int64 {
var primeNumbers []int64
var res PrimeResult
var prev int64
channel := make(chan PrimeResult)
defer close(channel)
go firePrimeCalculations(min, max, channel)
prev = 0
for i := min; i <= max; i++ {
res = <-channel
if res.prime {
primeNumbers = append(primeNumbers, res.number)
done := 100 * (i - min) / (max - min)
if prev != done {
fmt.Printf("%d %% done.\n", done)
prev = done
}
}
}
return primeNumbers
}
func isPrime(candidate int64) bool {
var i, limit int64
if candidate == 2 {
return true
}
if math.Mod(float64(candidate), 2) == 0 {
return false
}
limit = int64(math.Ceil(math.Sqrt(float64(candidate))))
for i = 3; i <= limit; i += 2 { //Only odd numbers
if math.Mod(float64(candidate), float64(i)) == 0 {
return false
}
}
return true
}
The prime number calculation is basically there to get some calculation.
2016/10/11 15:36:45 Parsing trace...