/mobile Handheld Friendly website

 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.970.386081400  42% 68% 67% 86%
600,0008.412.6521,4881400  90% 90% 91% 57%
6,000,00070.3321.4921,6001400  83% 86% 86% 82%

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 Runtime Engine version 3.2.5 (master/4c1198f Tue Oct 29 09:53:35 PDT 2013)
LLVM: yes(3.3svn-mono-mono/8bdedb5)
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 Oct 2013 19:11:00 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 --gc=sgen 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
4074443 zero
3957517 zero
3968040 zero
 one two zero zero zero zero zero zero

 blue red yellow red yellow blue red yellow red blue
1185838 zero
1195693 zero
1194049 zero
1200338 zero
1202354 zero
1204614 zero
1201496 zero
1221906 zero
1195776 zero
1197936 zero
 one two zero zero zero zero zero zero

Revised BSD license

  Home   Conclusions   License   Play