performance measurements

Each table row shows performance measurements for this Go program with a particular command-line input value N.

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load
60,0000.080.09?957  0% 0% 13% 100%
600,0000.800.81760957  0% 1% 1% 100%
6,000,0008.008.00764957  0% 1% 1% 100%

Read the ↓ make, command line, and program output logs to see how this program was run.

Read chameneos-redux benchmark to see what this program should do.

 notes

go version go1.4 linux/386

 chameneos-redux Go #5 program source code

/* The Computer Language Benchmarks Game
 * http://benchmarksgameshootout.alioth.debian.org/
 *
 * contributed by The Go Authors.
 * modified by roger peppe
 * 
 */

package main

import (
   "flag"
   "fmt"
   "strconv"
   "sync"
)

const (
   blue = iota
   red
   yellow
   ncol
)

var complement = [...]int{
   red | red<<2: red,
   red | yellow<<2: blue,
   red | blue<<2: yellow,
   yellow | red<<2: blue,
   yellow | yellow<<2: yellow,
   yellow | blue<<2: red,
   blue | red<<2: yellow,
   blue | yellow<<2: red,
   blue | blue<<2: blue,
}

var colname = [...]string{
   blue: "blue",
   red: "red",
   yellow: "yellow",
}

// information about the current state of a creature.
type info struct {
   colour int // creature's current colour.
   name   int // creature's name.
}

// if mate is nil, it indicates there's no creature currently waiting
// otherwise the creature's info is stored in info, and
// it is waiting to receive its mate's information on the mate channel.
type Place struct {
   sync.Mutex
   n    int         // current number of encounters.
   mate chan<- info // creature waiting when non-nil.
   info info        // info about creature waiting.
}

// result sent by each creature at the end of processing.
type result struct {
   met  int
   same int
}

var n = 600

func main() {
   flag.Parse()
   if flag.NArg() > 0 {
      n, _ = strconv.Atoi(flag.Arg(0))
   }

   for c0 := 0; c0 < ncol; c0++ {
      for c1 := 0; c1 < ncol; c1++ {
         fmt.Printf("%s + %s -> %s\n", colname[c0], colname[c1], colname[complement[c0|c1<<2]])
      }
   }
   fmt.Print("\n")

   pallmall([]int{blue, red, yellow})
   pallmall([]int{blue, red, yellow, red, yellow, blue, red, yellow, red, blue})
}

func pallmall(cols []int) {

   // invariant: meetingplace always contains a value unless a creature
   // is currently dealing with it (whereupon it must put it back).
   meetingplace := new(Place)
   ended := make(chan result)
   msg := ""
   for i, col := range cols {
      go creature(info{col, i}, meetingplace, ended)
      msg += " " + colname[col]
   }
   fmt.Println(msg)
   tot := 0
   // wait for all results
   for _ = range (cols) {
      result := <-ended
      tot += result.met
      fmt.Printf("%v%v\n", result.met, spell(result.same, true))
   }
   fmt.Printf("%v\n\n", spell(tot, true))
}

// in this function, variables ending in 0 refer to the local creature,
// variables ending in 1 to the creature we've met.
func creature(info0 info, m *Place, ended chan result) {
   c0 := make(chan info)
   met := 0
   same := 0
   for {
      var othername int
      // get access to rendez data and decide what to do.
      m.Lock()
      switch {
      case m.n >= n:
         // if no more meetings left, then send our result data and exit.
         m.Unlock()
         ended <- result{met, same}
         return

      case m.mate == nil:
         // no creature waiting wait for someone to meet us,
         // get their info and send our info in reply.
         m.info = info0
         m.mate = c0
         m.Unlock()
         info1 := <-c0
         othername = info1.name
         info0.colour = complement[info0.colour|info1.colour<<2]

      default:
         // another creature is waiting for us with its info
         // increment meeting count,
         // send them our info in reply.
         mate := m.mate
         m.n++
         m.mate = nil
         info1 := m.info
         m.Unlock()
         mate <- info0
         othername = info1.name
         info0.colour = complement[info0.colour|info1.colour<<2]
      }
      if othername == info0.name {
         same++
      }
      met++
   }
}

var digits = [...]string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}

func spell(n int, required bool) string {
   if n == 0 && !required {
      return ""
   }
   return spell(n/10, false) + " " + digits[n%10]
}

 make, command-line, and program output logs

Fri, 12 Dec 2014 02:59:12 GMT

MAKE:
/usr/local/src/go/bin/go build -o chameneosredux.go-5.go_run
0.29s to complete and log all make actions

COMMAND LINE:
./chameneosredux.go-5.go_run 6000000

PROGRAM OUTPUT:
blue + blue -> blue
blue + red -> yellow
blue + yellow -> red
red + blue -> yellow
red + red -> red
red + yellow -> blue
yellow + blue -> red
yellow + red -> blue
yellow + yellow -> yellow

 blue red yellow
4000000 zero
4000000 zero
4000000 zero
 one two zero zero zero zero zero zero

 blue red yellow red yellow blue red yellow red blue
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
 one two zero zero zero zero zero zero

Revised BSD license

  Home   Conclusions   License   Play