performance measurements

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

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load
60,0000.420.4323,6241400  0% 2% 2% 100%
600,0002.842.8528,6641400  0% 1% 1% 100%
6,000,00026.7126.7232,7121400  1% 0% 0% 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

Mono JIT compiler version 3.4.1 (master/ea46441 Mon Apr 28 17:45:05 PDT 2014)
LLVM: yes(3.4svn-mono-mono/e656cac)
GC: sgen

 chameneos-redux C# Mono program source code

/* The Computer Language Benchmarks Game
   http://benchmarksgame.alioth.debian.org/

   Adapted by Pascal Fresnay from Java version that was:
      contributed by Michael Barker
      based on a contribution by Luzius Meisser
*/

/**
 * This implementation uses standard C# threading (native threads).
 *
 * This implementation simply adds the new functionality to the orginal
 * implementation by Luzius Meisser from old chameneos task.  The interesting
 * part of this implementation, is that while a creature is waiting it does not
 * block its thread, rather it spins in a loop using a Thread.Sleep(0).
 */


using System;
using System.Threading;
using System.Text;
public class chameneosredux {

   public enum Colour {
      blue,
      red,
      yellow
   }

   private static Colour doCompliment(Colour c1, Colour c2) {
      switch (c1) {
      case Colour.blue:
         switch (c2) {
         case Colour.blue:
            return Colour.blue;
         case Colour.red:
            return Colour.yellow;
         case Colour.yellow:
            return Colour.red;
         default: break;
         }
         break;
      case Colour.red:
         switch (c2) {
         case Colour.blue:
            return Colour.yellow;
         case Colour.red:
            return Colour.red;
         case Colour.yellow:
            return Colour.blue;
         default: break;
         }
         break;
      case Colour.yellow:
         switch (c2) {
         case Colour.blue:
            return Colour.red;
         case Colour.red:
            return Colour.blue;
         case Colour.yellow:
            return Colour.yellow;
         default: break;
         }
         break;
      default: break;
      }
      throw new Exception();
   }

   sealed class MeetingPlace {

      private int meetingsLeft;

      public MeetingPlace(int meetings) {
         this.meetingsLeft = meetings;
      }

      private Colour? firstColour = null;
      private int firstId = 0;
      Future current;

      public Pair meet(int id, Colour c){
         Future newPair;
         lock (this) {
            if (meetingsLeft == 0) {
               throw new Exception("Finished");
            } else {
               if (firstColour == null) {
                  firstColour = c;
                  firstId = id;
                  current = new Future();
               } else {
                  Colour newColour = doCompliment(c, firstColour.Value);
                  current.Item = new Pair(id == firstId, newColour);
                  firstColour = null;
                  meetingsLeft--;
               }
               newPair = current;
            }
         }
         return newPair.Item;
      }
   }

   public sealed class Future {

      private Pair? t;
      
      public Pair Item
      {
         get
         {
            while (t == null)
            {
               Thread.Sleep(0);
            }
            return t.Value;
         }
         // need synchronization ?
         set
         {
            t = value;
         }
      }
   }

   sealed class Creature{

      private readonly MeetingPlace place;
      private int count = 0;
      private int sameCount = 0;
      private Colour colour;
      private int id;

      public Creature(MeetingPlace place, Colour colour) {
         this.place = place;
         this.id = this.GetHashCode();
         this.colour = colour;
      }

      public void run() {
         try {

            while (true) {
               Pair p = place.meet(id, colour);
               colour = p.colour;
               if (p.sameId) {
                  sameCount++;
               }
               count++;
            }

         } catch (Exception) {}
      }

      public int Count {
         get
         {
            return count;
         }
      }

      public override String ToString() {
         return count.ToString() + getNumber(sameCount);
      }
   }

   private static void run(int n, params Colour[] colours) {
      MeetingPlace place = new MeetingPlace(n);
      Creature[] creatures = new Creature[colours.Length];
      for (int i = 0; i < colours.Length; i++) {
         Console.Write(" " + colours[i]);
         creatures[i] = new Creature(place, colours[i]);
      }
      Console.WriteLine();
      Thread[] ts = new Thread[colours.Length];
      for (int i = 0; i < colours.Length; i++) {
         ts[i] = new Thread(creatures[i].run);
         ts[i].Start();
      }

      foreach (Thread t in ts) {
            t.Join();
      }

      int total = 0;
      foreach (Creature creature in creatures) {
         Console.WriteLine(creature);
         total += creature.Count;
      }
      Console.WriteLine(getNumber(total));
      Console.WriteLine();
   }

   public static void Main(String[] args) {

      int n = 600;
      if(args.Length > 0)
         n = Int32.Parse(args[0]);

      printColours();
      Console.WriteLine();
      run(n, Colour.blue, Colour.red, Colour.yellow);
      run(n, Colour.blue, Colour.red, Colour.yellow, Colour.red, Colour.yellow,
            Colour.blue, Colour.red, Colour.yellow, Colour.red, Colour.blue);
   }

   public struct Pair {
      public readonly bool sameId;
      public readonly Colour colour;

      public Pair(bool sameId, Colour c) {
         this.sameId = sameId;
         this.colour = c;
      }
   }

   private static String[] NUMBERS = {
      "zero", "one", "two", "three", "four", "five",
      "six", "seven", "eight", "nine"
   };

   private static String getNumber(int n) {
      StringBuilder sb = new StringBuilder();
      String nStr = n.ToString();
      for (int i = 0; i < nStr.Length; i++) {
         sb.Append(" ");
         sb.Append(NUMBERS[(int)Char.GetNumericValue(nStr[i])]);
      }

      return sb.ToString();
   }

   private static void printColours() {
      printColours(Colour.blue, Colour.blue);
      printColours(Colour.blue, Colour.red);
      printColours(Colour.blue, Colour.yellow);
      printColours(Colour.red, Colour.blue);
      printColours(Colour.red, Colour.red);
      printColours(Colour.red, Colour.yellow);
      printColours(Colour.yellow, Colour.blue);
      printColours(Colour.yellow, Colour.red);
      printColours(Colour.yellow, Colour.yellow);
   }

   private static void printColours(Colour c1, Colour c2) {
      Console.WriteLine(c1 + " + " + c2 + " -> " + doCompliment(c1, c2));
   }


}

 make, command-line, and program output logs

Tue, 29 Apr 2014 08:42:28 GMT

MAKE:
mv chameneosredux.csharp chameneosredux.cs
/usr/local/bin/mcs  -optimize+ -platform:x64 -out:chameneosredux.csharp_run chameneosredux.cs
rm chameneosredux.cs
0.23s to complete and log all make actions

COMMAND LINE:
/usr/local/bin/mono --llvm chameneosredux.csharp_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
3993649 zero
3994413 zero
4011938 zero
 one two zero zero zero zero zero zero

 blue red yellow red yellow blue red yellow red blue
1211066 zero
1202996 zero
1212295 zero
1201511 zero
1198268 zero
1197053 zero
1195869 zero
1194299 zero
1196275 zero
1190368 zero
 one two zero zero zero zero zero zero

Revised BSD license

  Home   Conclusions   License   Play