Yup you heard it right, Super­Fun Town has been added to Hi5 and is cur­rently one of the fea­tured games in the revamped Games page. Start play­ing today!

Share

Stum­bled across ic#code’s free ebook ‘The fine art of com­ment­ing’ this morn­ing, it’s from 2002 but every­thing still applies, you can down­load it here.

The book cov­ers com­ment­ing in gen­eral and not just C#, but in rela­tion to C# here’s the list of the pre­de­fined xml tags you can use in com­ments (some­thing I have to search every time..):

<c> Marks a part of a com­ment to be for­mat­ted as code
<code> As above, but multiline
<exam­ple> For embed­ding exam­ples in com­ments, usu­ally uses <c>
<excep­tion>* Doc­u­ments an Excep­tion class
<include>* Includes doc­u­men­ta­tion from other files
<list> A list of <term>s defined by <description>s
<para> Struc­tures text blocks, e.g. in a <remark>
<param>* Describes a method parameter
<paramref>* Indi­cates that a word is used as ref­er­ence to a parameter
<per­mis­sion>* Gives the access per­mis­sions to a member
<remarks> For overview of what a given class or other type does
<returns> Descrip­tion of the return value
<see>* Refers to a mem­ber or field available
<seealso>* As above, but dis­plays a ‘See also’ section
<sum­mary> A sum­mary of the object
<value> Describes a property

* val­i­dated by the C# compiler

Share

Hav­ing spent quite a bit of time cod­ing in F# recently I have thor­oughly enjoyed the expe­ri­ence of cod­ing in a func­tional style and come to really like the fact you can do so much with so lit­tle code.

One of the counter-claims against F# has always been the con­cerns over per­for­mance in the most per­for­mance crit­i­cal appli­ca­tions, and with that in mind I decided to do a lit­tle exper­i­ment of my own using C# (LINQ & PLINQ) and F# to gen­er­ate all the prime num­bers under a given max value.

The LINQ and PLINQ meth­ods in C# look some­thing like this:

private static void DoCalcSequentially(int max)
{
    var numbers = Enumerable.Range(3, max-3);
    var query =
        numbers
            .Where(n => Enumerable.Range(2, (int)Math.Sqrt(n))
            .All(i => n % i != 0));
    query.ToArray();
}

private static void DoCalcInParallel(int max)
{
    var numbers = Enumerable.Range(3, max-3);
    var parallelQuery =
        numbers
            .AsParallel()
            .Where(n => Enumerable.Range(2, (int)Math.Sqrt(n))
            .All(i => n % i != 0));
    parallelQuery.ToArray();
}

The F# ver­sion on the other hand uses the fairly opti­mized algo­rithm I had been using in most of my project euler solutions:

let mutable primeNumbers = [2]

// generate all prime numbers under <= this max
let getPrimes max =
    // only check the prime numbers which are <= the square root of the number n
    let hasDivisor n =
        primeNumbers
        |> Seq.takeWhile (fun n' -> n' <= int(sqrt(double(n))))
        |> Seq.exists (fun n' -> n % n' = 0)

    // only check odd numbers <= max
    let potentialPrimes = Seq.unfold (fun n -> if n > max then None else Some(n, n+2)) 3
    // populate the prime numbers list
    for n in potentialPrimes do if not(hasDivisor n) then primeNumbers <- primeNumbers @ [n]

    primeNumbers

Here’s the aver­age exe­cu­tion time in mil­lisec­onds for each of these meth­ods over 3 runs for max = 1000, 10000, 100000, 1000000:

image

Have to admit this doesn’t make for a very com­fort­able reading…on aver­age the F# ver­sion, despite being opti­mized, runs over 3 – 6 times as long as the stan­dard LINQ ver­sion! The PLINQ ver­sion on the other hand, is slower in com­par­i­son to the stan­dard LINQ ver­sion when the set of data is small as the over­head of par­ti­tion­ing, col­lat­ing and coor­di­nat­ing the extra threads actu­ally slows things down, but on a larger dataset the ben­e­fit of par­al­lel pro­cess­ing starts to shine through.

UPDATE 13/11/2010:

Thanks for Jaen’s com­ment, the cause for the F# ver­sion of the code to be much slower is because of this line:

primeNumbers <- primeNumbers @ [n]

because a new list is con­structed every time and all ele­ments from the pre­vi­ous list copied over.

Unfor­tu­nately, there’s no way to add an ele­ment to an exist­ing List or Array in F# with­out get­ting a new list back (at least I don’t know of a way to do this), so to get around this per­for­mance hand­i­cap the eas­i­est way is to make the prime num­bers list a generic List instead (yup, luck­ily you are free to use CLR types in F#):

open System.Collections.Generic

// initialize the prime numbers list with 2
let mutable primeNumbers = new List<int>()
primeNumbers.Add(2)

// as before
...

    // populate the prime numbers list
    for n in potentialPrimes do if not(hasDivisor n) then primeNumbers.Add(n)

    primeNumbers

With this change, the per­for­mance of the F# code is now com­pa­ra­ble to that of the stan­dard LINQ version.

Share

Ever tried to use IEnumerable<T>.Sum on an array of unsigned long inte­gers? Well, you can’t, because the Sum method has not been imple­mented for ulong or ulong?, so to fill in the gap here’s the exten­sion meth­ods you need using more or less the same code as the exist­ing Sum methods:

[CheckParameters]
public static ulong Sum([NotNull] this IEnumerable<ulong> source)
{
    var sum = 0UL;
    foreach (var number in source)
    {
        sum += number;
    }
    return sum;
}

[CheckParameters]
public static ulong? Sum([NotNull] this IEnumerable<ulong?> source)
{
    var sum = 0UL;
    foreach (var nullable in source)
    {
        if (nullable.HasValue)
        {
            sum += nullable.GetValueOrDefault();
        }
    }
    return sum;
}

[CheckParameters]
public static ulong Sum<T>([NotNull] this IEnumerable<T> source, Func<T, ulong> selector)
{
    return source.Select(selector).Sum();
}

[CheckParameters]
public static ulong? Sum<T>([NotNull] this IEnumerable<T> source, Func<T, ulong?> selector)
{
    return source.Select(selector).Sum();
}

I used some cus­tom Post­Sharp attrib­utes here to do the para­me­ter val­i­da­tion, but you can just as eas­ily sub­sti­tute them with if null then throw excep­tion code blocks.

UPDATE 10/11/2010:

Using the dynamic type in .Net 4 you can make these exten­sion meth­ods even more use­ful by mak­ing them usable with other value types too.

Tra­di­tion­ally for exten­sion meth­ods like Sum, you’d have to pro­vide an over­load for each numeric value type (int, uint, long, etc.) because these numeric value types don’t have a com­mon super type which defines the numeric oper­a­tors +, -, /, *, etc.

For­tu­nately, you can now negate this com­pile time lim­i­ta­tion by mak­ing it a run­time deci­sion using the new dynamic capabilities:

public static T Sum<T>(this IEnumerable<T> source) where T : struct
{
    return source.Aggregate(default(T), (current, number) => (dynamic) current + number);
}
public static T? Sum<T>(this IEnumerable<T?> source) where T : struct
{
    return source.Where(nullable => nullable.HasValue)
                 .Aggregate(
                     default(T),
                     (current, nullable) => (dynamic) current + nullable.GetValueOrDefault());
}
public static V Sum<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct
{
    return source.Select(selector).Sum();
}
public static V? Sum<T, V>(this IEnumerable<T> source, Func<T, V?> selector) where V : struct
{
    return source.Select(selector).Sum();
}

The obvi­ous fal­lacy with this approach is that you can now pass cus­tom struc­tures with no defined + oper­a­tor into these exten­sion meth­ods and no com­pile errors will be thrown, but a Run­time­BinderEx­cep­tion will be thrown by the DLR at run­time with a mes­sage like this:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Oper­a­tor ‘+’ can­not be applied to operands of type ‘xxx’ and ‘xxx’

Share

Since migrat­ing to Win­dows Server 2008 Dat­a­cen­ter for our Ama­zon EC2 instances I have noticed on many occa­sions that when a new instance is start­ing up RAC agent will cause the CPU to spike up to 100% for a good half an hour, at times the CPU spike never comes down and effec­tively ren­ders the instance unusable..

After some dig­ging around, I found this arti­cle which tells you how to dis­able the RAC agent:

http://dotnetwizard.net/tutorials/stop-racagent-from-hogging-your-pc-resources/

 

In case the link stops work­ing in the future, here’s the 4 steps you need to do:

1. go to Con­trol Panel –> Admin­is­tra­tive Tools –> Com­puter Management

2. nav­i­gate to Sys­tem Tools –> Task Sched­uler –> Task Sched­uler Library –> Microsoft –> Win­dows –> RAC

3. right click RAC, select View –> Show Hid­den Tasks

4. right click on the dis­played task, and select Dis­able

Share