Showing posts with label CLR. Show all posts
Showing posts with label CLR. Show all posts

Wednesday, May 15, 2013

Parallel integer summation challenge Erlang vs CLR/C#

Today we have done an interesting benchmark in C# and Erlang. Basically the point was to compare the brevity and performance of two inherently different langs/approaches:

Erlang r16b:

$ cat t.erl

-module(t).
-export([t/0, t/1, ct/1, ct/2]).

-define(DEF_CNT, 10000000).

t() ->
    t(?DEF_CNT).
t(N) when is_integer(N) ->
    time_it(fun() -> test(N) end, N).

ct(Threads) ->
    ct(?DEF_CNT, Threads).
ct(N, Threads) when is_integer(N), is_integer(Threads) ->
    time_it(fun() -> ctest(N, Threads) end, N * Threads).

time_it(Fun, Divisor) ->
    {T, Result} = timer:tc(Fun),
    {T / (Divisor/1000000) / 1000, Result}.

ctest(N, M) ->
    Pids = spawner(self(), N, M),
    lists:foldl(fun(Pid, S) ->
        receive {Pid, Sum} -> S+Sum end
    end, 0, Pids).

spawner(_, _, 0) ->
    [];
spawner(Owner, N, M) ->
    [spawn(fun() -> loop(Owner, N) end) | spawner(Owner, N, M-1)].

loop(Pid, N) ->
    Sum = test(N),
    Pid ! {self(), Sum}.

test(N) -> test(N, 0).

test(0, M) -> M;
test(N, M) -> test(N-1, M+1).


C#, NET 4:

private void button4_Click(object sender, EventArgs e)
{
    const int CNT = 100000000;
    const int SPLIT = 1000000;

    var tasks = new Task[CNT / SPLIT];
       
         

    var w = Stopwatch.StartNew();
          
    for(int i=0,start=0; i    {
    tasks[i] = new Task( () =>
                                {
                                    long lsum = 0;
                                    long end = start + SPLIT;
                                    for(int c=start; c                                    return lsum;
                                }
                            );
    tasks[i].Start();
    }

    long sum = tasks.Sum( t => t.Result);
         
    w.Stop();

    var rate = CNT / (w.Elapsed.TotalSeconds);

    Text = string.Format("Total: {0} in {1} ms  at {2}/sec  {3} msec/million ",

  CNT,
 w.Elapsed.TotalMilliseconds, 
rate,
w.Elapsed.TotalMilliseconds / (CNT / 1000000)
);

    var s = sum;
    Text+= s.ToString();
}



Test results are really interesting:
  .NET      0.22 msec per million
  Erlang does this is 1.5 msec per million

CLR is 6.8 faster for this test.

Some other facts.  Linear loop single threaded that sums integers (not optimized out of code, I confirmed in disassembler)

PHP code:
 $CNT = 10000000;
 $sum = 0;
 $w = microtime(true);
 for($i=0; $i<$CNT; $i++) $sum += 1;
 $w = round((microtime(true)-$w)*1000,0);
 echo($w);


PHP standard runtime:  1040 ms
C#:                                     2ms

CLR is 500 times faster that PHP for this simple test