Show / Hide Table of Contents

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<long>[CNT / SPLIT];

  var w = Stopwatch.StartNew();

  for(int i=0,start=0; i < CNT / SPLIT; i++)
  { 
    tasks[i] = new Task<long>( () =>
                          {
                            long lsum = 0;
                            long end = start + SPLIT;
                            for(int c=start; c<end; c++)
                              lsum++;
                            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));

  Text += sum.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:  1040ms 
C#:                    2ms

CLR is 500 times faster that PHP for this simple test


Dmitriy Khmaladze
May 15, 2013

Back to top Copyright © 2006-2018 Agnicore Inc
Generated by DocFX