Phillip Trelford's blog... evidently
when your only tool is an analogy, everything looks like a simile.

C# is not C

February 13, 2010 23:57 by phil

Chances are that if you are habitually applying C-style Micro-Optimization tricks when coding C#, like moving variable declarations out of loops, you are probably:

  1. Prematurely optimizing
  2. Doing it completely wrong

mccarthy-youre-doing-it-wrong-s

To demonstrate the point lets start by ignoring that there is a perfectly good Array.Reverse function in the framework and write our own:

static void Reverse1<T>(T[] xs)
{
    for (int i = 0; i < xs.Length / 2; i++)
    {
        T x = xs[i];
        xs[i] = xs[xs.Length - 1 - i];
        xs[xs.Length - 1 - i] = x;
    }
}

Now micro-optimize by taking the temp declaration out of the loop:

static void Reverse2<T>(T[] xs)
{
    T x;
    for (int i = 0; i < xs.Length / 2; i++)
    {
        x = xs[i];
        xs[i] = xs[xs.Length - 1 - i];
        xs[xs.Length - 1 - i] = x;
    }
}

 

The IL (byte code) generated for both implementations is identical in both release and debug builds. If you don’t believe me then check it for yourself by using the ildasm tool.

Another micro-optimization would be to store a copy of the array length in a local variable:

static void Reverse3<T>(T[] xs)
{           
    int len = xs.Length;
    for (int i = 0; i < len / 2; i++)
    {
        T x = xs[i];
        xs[i] = xs[len - 1 - i];
        xs[len - 1 - i] = x;
    }
}

 

This does actually result in the generation of different IL code, however IL generation is only part of the story. The difference in execution time between these implementations is negligible. The reason is that the IL code is just-in-time (JIT) compiled to machine code before execution and this compilation step will apply further optimizations.

Premature optimization is wrong on so many levels:

  • the optimization was probably unnecessary anyway
  • code can become less readable for no tangible benefit
  • you’re double guessing 2 compilation steps
  • you’re probably not even considering high level optimizations
    Further reading:

Pareto principle

The Sad Tragedy of Micro-Optimization Theater

Micro-Optimization and Meatballs

Micro-optimization tips to increase performance


Tags:
Categories: C# | .Net
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

C++ vs C# vs F# vs Haskell

November 29, 2009 08:36 by Phil

Since I first posted an F# solution to Left-Truncatable Primes, C# and Haskell have entered the frame, and although this is not a good problem for a serious comparison of languages, I think it is still interesting.

So lets start at the beginning, Dominic Penfold initially posed the problem and gave an efficient algorithm implemented in C++ (39 lines):

bool IsPrime(int num)
{
    int sqrt = 1 + sqrtf(num);
    for (int i=2; i<sqrt; i++)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}
 
int NthLeftTruncatablePrime(int target)
{
    std::vector<int> PrimeRoots;
    PrimeRoots.push_back(2);
    PrimeRoots.push_back(3);
    PrimeRoots.push_back(5);
    PrimeRoots.push_back(7);
    int start = 0;
    int tens = 10;    
    while(true)
    {
        int end = PrimeRoots.size();
        for (int i=1; i<10; i++)
        {
            for (int pos = start; pos< end; pos++)
            {
                int newprime = tens * i + PrimeRoots[pos];
                if (IsPrime(newprime))
                {
                    PrimeRoots.push_back(newprime);
                    if (PrimeRoots.size()==target)                                      
                        return newprime;                    
                }
            }
        }
        start = end;
        tens *= 10;
    }
}

 

Performance was considerably faster when 32-bit integers were switched for 64-bit integers.

The C++ code is very easily converted into C# (35 lines):

static bool IsPrime(int num)
{
    int sqrt = 1 + (int ) System.Math.Sqrt(num);
    blue">for (int i = 2; i < sqrt; i++)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}

static int NthLeftTruncatedPrime(int target)
{
    var primeRoots = new List<int>() { 2, 3, 5, 7};               
    int start = 0;
    int tens = 10;
    while (true)
    {
        int end = primeRoots.Count;
        for (int i = 1; i < 10; i++)
        {
            for (int pos = start; pos < end; pos++)
            {
                int newprime = tens * i + primeRoots[pos];
                if (IsPrime(newprime))
                {
                    primeRoots.Add(newprime);
                    if (primeRoots.Count == target)
                        return newprime;
                }
            }
        }
        start = end;
        tens *= 10;
    }
}

 

Conversion to F# is only slightly trickier as there is no equivalent return statement, but similar behavior can be accomplished using yield (30 lines):

let IsPrime n =
    if n = 1 then false
    else    
        let max = n |> float |> sqrt |> int
        let rec Test = function
            | x when x > max -> true
            | x -> if (n % x) = 0 then false else Test (x+1)
        Test 2

let NthLeftTruncatablePrime n =
    let oneDigitPrimes = [2;3;5;7]          
    seq {            
        let primes = ref oneDigitPrimes        
        for tens = 1 to 8 do
            let acc = ref []
            for i=1 to 9 do 
                let newPrime = i * pown 10 tens                
                let primes' = ref !primes
                while (!primes').Length > 0 do                            
                    let x = newPrime+(!primes').Head
                    if IsPrime x then 
                        acc := x :: !acc
                        yield x
                    primes' := (!primes').Tail                    
                done                                     
            done         
            primes := !acc |> List.rev    
        done            
    }
    |> Seq.append oneDigitPrimes
    |> Seq.nth (n-1)

 

The extra overhead of generating a sequence can be avoided using instead recursion (25 lines including IsPrime function):

let NthLeftTruncatablePrime index =
    let rec Find digit factor primes primes' count acc =
        match digit, primes' with
        | 10, _ -> 
            let primes = List.rev acc
            Find 1 (10*factor) primes primes count []
        | _, [] ->
            Find (digit+1) factor primes primes count acc
        | _, prime::tail -> 
            let k = (digit * factor) + prime
            let count, acc =
                if IsPrime k then count+1, k::acc else count, acc 
            if count = index then k
            else Find digit factor primes tail count acc
    let primes = [2;3;5;7]
    if index <= 4 then List.nth primes (index-1)
    else Find 1 10 primes primes 4 []

 

Later Matt Curran (coincidentally another ex-games developer) got in on the act with a Haskell version (17 lines including a comment – although the lines are a little dense):

isPrime :: Int -> Bool
isPrime 1 = False
isPrime x = null $ take 1 [n | n <- [2..upperBound x], 0 == mod x n]
    where
        upperBound = floor . sqrt . fromIntegral

-- list of all left truncatable primes
ltps :: [Int]
ltps = ps 1 [0]
    where
        ps _ []      = []
        ps m prevMag = thisMag ++ (ps (m*10) thisMag)
            where
                thisMag = primes [x*m | x <- [1..9]] prevMag
                    where
                        primes [] _ = []
                        primes (m:mgs) bases = 
                            (filter isPrime [m+x | x <- bases]) ++ (primes mgs bases)

 

Results Breakdown by language

Language Lines of code Performance(ms)
C++ 39 5.213
C# 35 5.332
F# sequence 30 14.075
F# recursive 25 5.412
Haskell 17 ?

Note: the time is to generate the 1000th prime, and the same computer was used for all tests, as was release mode. Haskell time coming soon.

LeftTruncatablePrime.cpp (1.45 kb)

LeftTruncatablePrime.cs (1.58 kb)

LeftTruncatablePrime_seq.fs (1.53 kb)

LeftTruncatablePrime_rec.fs (1.36 kb)


Tags:
Categories: .Net | F# | C# | C++ | Haskell
Actions: E-mail | Permalink | Comments (13) | Comment RSSRSS comment feed

Software Architect 2009 Conference

October 1, 2009 08:33 by phil

For the last 2 days I’ve been attending the Software Architect 2009 conference located at the iconic Royal College of Physicians building opposite Regent's Park in central London. Overall the events have been interesting, that said, the content has not in general been particularly new or ground breaking, but that is probably the nature of the discipline. It has however been good to be reminded of key principles, to listen to the views of others, and as always I’ve found it quite thought provoking. For each talk I attended I’ve created an entry on Twitter @ptrelford:

Tim Ewald on Saving Software Architecture: "When you go too far up, abstraction-wise, you run out of oxygen" Joel on Architecture Astronauts

Kevin Seal on MorganDirect's client-side architecture: Swing app with Eclipse IDE look, blackboard pattern, detailed logs & takes screenshots

Kevlin Henney on Slicing design over time: take time estimate & half it, coding is performance art so practice, test cases are propositions.

Dave Wheeler on Coding a solid UI: "WPF is great", dependency properties are cool, do MVVM pattern, get an HCI expert & use Expression Blend

Richard Blewett on What's New in WF 4.0: Everything. Complete API rewrite. 3.5 favoured code based workflow. 4.0 declarative XAML is king.

Dino Esposito asks "How good are you at .NET software design?" Separation of concerns, OOD principles - prefer composition to inheritance etc

Kevlin Henney on Modelling in the age of agility: Most important aspect of modelling is the -ing, i.e. the social and collaborative aspects.

Simon Brown on "Documenting your software architecture - why and how?" Start with a context and set the scene. Put yourself in others shoes.

Most popular analogy: Construction (Tim Ewald & Kevlin Henney)

Favourite example: Fast-Track Construction of the Empire State Building (Kevlin Henney)

Best term usage: idempotent (Simon Brown)

Best vocabularly usage: pontificate (Kevlin Henney)

Only search term suggestion: Death by UML Fever (Kevlin Henney again)


Tags:
Categories: .Net
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

F# Units of Measure talk at Open Source eXchange III

July 26, 2009 03:36 by phil

The Open Source eXchange III was a mini-conference where members of the ALT.NET community talked about their favourite alternative .NET tools that increase programmer productivity. Units of Measure is a cool language feature in F#, developed by Andrew Kennedy, that lets you easily annotate values with units like metres, kilograms or seconds. Then F# type inference kicks in to give you automatic checking of your unit types at design and compile time, but cost you nothing at run time, e.g.

  let gravityOnEarth = 9.8f<m/s^2> // Acceleration

Following a bit of a Apollo 40th Anniversary theme, I presented 3 code samples (attached):

  • Statistics
  • Orbital Mechanics
  • Lunar Lander

Resources:

Further reading:


Tags:
Categories: .Net | F#
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Skills Matter: F# Intro Talk Material - Slides & Code Samples

May 22, 2009 08:32 by phil

Thanks to everyone who made it down to Skills Matter on Tuesday for Scott Cowan's Lucene.Net talk and my F# Introduction talk. There was a great turnout, with more chairs needing to be brought in, plus some excellent questions, and also a good group for the pub after. My slides are attached to this post and a video/podcast should be available soon here:

http://skillsmatter.com/podcast/open-source-dot-net/phil-trelford-f-introduction 

I have also put the code samples from my F# Intro talk up on the F# Wiki:

  • fsweet sample WFP Twitter client script (<200 lines)
  • Mastermind sample WPF mini-game (<300 lines)

Below a screen shot of the fsweet script, showing a Twitter friends timeline, used to make a live Twitter update during the talk. 

screenshot of fsweet F# Twitter client

FSharpIntroduction.pptx (376.59 kb)

fsweet.fsx (8.58 kb)


Tags: , ,
Categories: .Net | F# | Twitter
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Announcing My F# Introduction Talk on Tuesday 19th May, 2009 @ Skills Matter in London

May 13, 2009 17:43 by phil

This talk is intended to provide a quick introduction to the language for existing developers, along the way comparing features with other programming languages including C#, C++ and Python. Expect plenty of code samples culminating in a playable mini-game written with F# in less than 300 lines!

Register free here: http://skillsmatter.com/podcast/open-source-dot-net/phil-trelford-f-introduction 

My previous F# talks 

My public F# game samples


Tags:
Categories: .Net | F#
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed