Stupid C++ vs C# performance comparison

I found out that there is real test than the little one i did here. In fact the main interest of the post is this spreadsheet :

I recently did a simple and stupid comparison test between C++ (g++) and C# .Net (mono).

My point here is that C# can actually be considered as a very fast language. It allows automatic hardware-specific optimization. The only real drawback you have in the .Net framework is the garbage collector. It prevents the C# .Net it from being a realtime language/framework. But does it really matter for you ?

The purpose of the following test is to show that C++ isn’t faster than C# “as is”. I KNOW C# can not be faster than C++ because C# can do few hardware specific optimizations when you can do all of them in C++, because all the systems calls have to be done in C/C++ and because there’s no such thing like Template and forced inlining in C#.

But if you’re searching for arguments to choose C# .Net over native C++, you should also consider these :

SO ! Here is the test…

I wrote these two sample programs :

One in C++ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
long stupidThing( long nb ) {
	long out = 1;
	while( nb > 0 )
		out *= nb--;
 
 
	return out;
}
 
int main() {
 
	long total = 0;
 
	for( int i = 0; i < 1000000; ++i )
		for( long l = 0; l < 100; ++l )
			total += stupidThing( l );
 
	cout << "Total : " << total << endl;
 
	return 0;
}

One in C# :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
 
namespace test {
        class Program {
                static long stupidThing( long nb ) {
                        long ret = 1;
                        while ( nb > 0 )
                                ret *= nb--;
                        return ret;
                }
 
                static void Main( string[] args ) {
 
                        long total = 0;
 
                        for ( int i = 0; i < 1000000; ++i )
                                for ( long l = 0; l < 100; ++l )
                                        total += stupidThing( l );
                        Console.WriteLine( "Total : {0}", total );
                }
        }
}

First of all, I open a shell in real-time priority, because I don’t want my other processses to mess with my tests :

1
# rtprio 99 bash

Then I compile the two programs :

1
2
# gmcs test.cs
# g++ -O4 test.cpp -o test

And then I launch my test :

On a 64 bits host :

1
Kernel : 2.6.9-023stab051.3-smp #1 SMP Wed Nov 4 18:36:34 MSK 2009 x86_64 x86_64 x86_64 GNU/Linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# time ./test ; time ./test ; time ./test ; time mono test.exe ; time mono test.exe ; time mono test.exe
Total : -6192109806162068864
 
real    0m12.433s
user    0m12.394s
sys     0m0.049s
Total : -6192109806162068864
 
real    0m12.415s
user    0m12.411s
sys     0m0.014s
Total : -6192109806162068864
 
real    0m12.430s
user    0m12.411s
sys     0m0.026s
Total : -6192109806162068864
 
real    0m10.311s
user    0m10.287s
sys     0m0.029s
Total : -6192109806162068864
 
real    0m10.254s
user    0m10.247s
sys     0m0.011s
Total : -6192109806162068864
 
real    0m10.250s
user    0m10.255s
sys     0m0.012s

C# clearly beats C++ here. Well

On a 32 bits host :

1
Kernel : 2.6.30-2-686 #1 SMP Fri Dec 4 00:53:20 UTC 2009 i686 GNU/Linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# time ./test ; time ./test ; time ./test ; time mono test.exe ; time mono test.exe ; time mono test.exe
Total : 100461056
 
real    1m10.927s
user    1m7.376s
sys     0m0.056s
Total : 100461056
 
real    1m12.590s
user    1m8.976s
sys     0m0.020s
Total : 100461056
 
real    1m13.279s
user    1m9.532s
sys     0m0.056s
Total : -6192109806162068864
 
real    2m22.492s
user    2m15.260s
sys     0m0.136s
Total : -6192109806162068864
 
real    2m23.002s
user    2m15.760s
sys     0m0.104s
Total : -6192109806162068864
 
real    2m25.102s
user    2m17.709s
sys     0m0.144s

C++ beats C# here, but in 32 bits C++ use other types whereas C# use the same. In C# long is always 64 bits, in C++ it can be 64 bits or 32 bits (depending on the current architecture).

D language

This is just a very short post about this language I recently discovered : the D language. As described on its little website : “D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. Special attention is given to the needs of quality assurance, documentation, management, portability and reliability.”.

It has most of the features of the java and the C# (best language ever), but it is fully compiled (no JVM or JIT stuff).

You should have a quick loot of its features on the Digital mars website (they’re the ones who created it).

I wonder if this language really has a future. C# (with the .Net framework) compiles and runs on every platform (thanks to mono), even on the iPhone, so it only remove the burden of the libraries required to run .net apps.
So, will it really beats its performance ? Because in C# is very fast (my next post will bring a stupid C++/C# performance comparison), and in C# avoiding time or memory consuming mistakes or multi-threading our code is very easy.

SPSecurity.RunWithElevatedPrivileges

If like me you’re wondering what exactly does SPSecurity.RunWithElevatedPrivileges, this is what I understand of it :

1
2
3
4
5
SPSecurity.RunWithElevatedPrivileges( () => {
    using( var newSite = new SPSite( site.Url ) ) {
        // your stuff
    }
});

Is equivalent to :

1
2
3
using( var newSite = new SPSite( site.Url, site.SystemAccount.Token ) ) {
    // your stuff
}

So if this is just to open an elevated privilege SPSite, it will be equivalent. But if you do some more complex things, as soon as you load a new SPSite it will open it with the original UserToken. And you lose…

C# .Net : How works automatic assembly versioning

When you choose to automatically generate a new version of your assembly at compilation, you have to set in the AssemblyInfo.cs file, this line :

1
2
3
4
5
6
7
8
9
10
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]

But what do these automatically generated numbers mean ? Well, chances are you don’t care. But one day after using this features for years I decided that I would.

  • The build number is the number of days since 01/01/2000
  • The revision number if the number of 2 seconds periods since 00:00 of this day

So… To get the compilation date of an assembly from its version, you would have to do :

1
2
var version = Assembly.GetExecutingAssembly().GetName().Version;
var date = new DateTime( 2000, 01, 01 ).AddDays( version.Build ).AddSeconds( version.Revision * 2 );

This feature is great if your need some atomic versionning of a particular library for instance. Each program using your library has its own version and you don’t risk to break working feature in future release of your library. And if you want to force the use of a newer version of a library within a particular application, you can use some assembly redirection.
But you should also note that if you deploy your assembly in the GAC (like it’s required to do with Sharepoint), you will have tons of “garbage” versions of your assembly. And there’s not “easy fix” for that.

Threads and Sharepoint

When you are using threads on sharepoint, you should take care of some little things :

  • The method used to launch the thread must have the “[STAThread]” attribute, it avoids some huge memory leaks.
  • If you need to use an SPSite from the calling site, you should copy its URL and UserToken to build a new SPSite in the new thread. If you’re not using that “design pattern”, things will get really wrong.
  • And of course you should dispose any sharepoint SPSite (SPWebs come from SPSite) allocated within the thread.

FBSL – Freestyle Basic Script Language

I met Gerôme Guillemin at work (well yes his personal page is totally outdated, he now has long hairs). He invented and supported FBSL, its surrounding development tools and some sample programs.

What is quite amazing with this script language is that it only requires a simple 450 KB exe file to run the FSBL scripts and all scripts perform very well (even with the OpenGL samples). The executed programs look like they are some native Win32 applications. I’d say it’s the perfect language for basic style languages addicted programmers.

You can get the latest version here.

The program is closed source but he’s ok to give the sources to people ready to get involved in the project.

By the way, Gerôme Guillemin is the first person I know to have played with the TI-74. I’ve spent a lot of time with this amazing single line calculator that my father owns.

Just a little sample code he sent me and I frapsed, encoded and uploaded on DL :

Rue Du Fric


For my english readers, you’re out of luck, this is a french-only post because it’s about a french online game : Rue Du Fric (can be translated to “street of money”, or maybe “street of gold”). But you can still have a look at the game if you’re interested.

Le jeu Rue Du Fric développé par la jeune startup BeeMoov est un jeu 100% javascript + AJAX. Il est très bien fini, il repose un univers extensible “à l’infini” au fur et à mesure de l’arrivée de nouveaux joueurs et l’occupation des sols. Vous pouvez acheter du terrain, placer des maisons dessus, gagner de l’argent, vendre et acheter des biens aux membres ou aux enchères, emprunter de l’argent à la banque et tout ça en interagissant en continu avec les autres.

Le jeu vient de démarrer, l’univers est déjà pas mal occupé avec une belle étendue de terrain couverte. Si vous êtes un geek, allez apprécier la prouesse technique et filez l’adresse à vos amis. Pour les autres, testez et éclatez vous.

BeeMoov a lancé il y a quelques années Ma Bimbo dont le succès ne se dément plus.

I love Google Buzz

I have played with Google Buzz on the web and on Google Maps 4.0 viagra en belgique. I’ve always been a huge fan of location based services, Google Maps w/Buzz is the ultimate one.

I like the world Google is building for us. There’s soo much data they allow us to access and build around everything.


Not related in anyway note : but well as nobody’s reading (even my girlfriend, isn’t that sad), I guess I can say useless things : I discovered the perfect “computer guy”‘s girlfriend : Leah Culver. She is pretty, smart, loves to code and she even likes hamburgers. And she doesn’t seem disturbed by crappy cars.
There must be something wrong with this girl, maybe she’s a succubus from hell.
I reached my quota of useless links.

Dirty WordPress APC caching

One or two weeks ago, I made a simple AB benchmarking test on a PHP site I built, it was ok. Then I did the same test on this blog and well… It was freaking slow… On 100 pages with 10 concurrent access, it took 3.5 to 10s to render. Well, I thought I should remove all these plugins I installed to make me and my blog famous (they didn’t perform well). It reduced the generation time by something like 100 ms.

So I had the brilliant idea to put everything in an APC cache, someone had the same idea.

So I approximatively did the same thing :

In the beginning of the index.php file :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if ( $_SERVER['REQUEST_METHOD'] == 'GET' ) {
 
        // This key will identify the page used
        $cacheKey = 'WP_'.$_SERVER['HTTP_HOST'].md5( $_SERVER['REQUEST_URI'] );
 
        // We try to get this page
        $cacheData = apc_fetch($cacheKey);
 
        // If we got something
        if (is_array( $cacheData )) {
 
                // We give each header
                foreach( $cacheData[0] as $h )
                        header( $h );
 
                // And the content
                die($cacheData[1]);
        }
 
        // If we're still here, we have no cache, so we'll start caching right now
        ob_start();
}

In the end of the index.php file :

1
2
3
// We have a cache key, it means we have something to cache
if ( $cacheKey )
        apc_store( $cacheKey, array( headers_list(), ob_get_contents() ), 900 );

And once it’s cached it performs well, to make it short it can serve in mean time of 1 ms and gives a general bandwidth of 200 MB/s. As you can guess, these tests are made locally and this is normal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[root@s15342968 ~]# ab -n 100  "http://florent.clairambault.fr/"
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
 
Benchmarking florent.clairambault.fr (be patient).....done
 
 
Server Software:        Apache/2.2.8
Server Hostname:        florent.clairambault.fr
Server Port:            80
 
Document Path:          /
Document Length:        161165 bytes
 
Concurrency Level:      1
Time taken for tests:   0.119899 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      16156100 bytes
HTML transferred:       16116500 bytes
Requests per second:    834.04 [#/sec] (mean)
Time per request:       1.199 [ms] (mean)
Time per request:       1.199 [ms] (mean, across all concurrent requests)
Transfer rate:          131585.75 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     1    1   0.0      1       1
Waiting:        0    0   0.1      0       1
Total:          1    1   0.0      1       1
 
Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      1
 100%      1 (longest request)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[root@s15342968 ~]# ab -n 100 -c 10  "http://florent.clairambault.fr/"
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
 
Benchmarking florent.clairambault.fr (be patient).....done
 
 
Server Software:        Apache/2.2.8
Server Hostname:        florent.clairambault.fr
Server Port:            80
 
Document Path:          /
Document Length:        161165 bytes
 
Concurrency Level:      10
Time taken for tests:   0.47897 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      16156100 bytes
HTML transferred:       16116500 bytes
Requests per second:    2087.81 [#/sec] (mean)
Time per request:       4.790 [ms] (mean)
Time per request:       0.479 [ms] (mean, across all concurrent requests)
Transfer rate:          329394.31 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     1    4   1.3      4      10
Waiting:        0    1   1.0      1       4
Total:          1    4   1.3      4      10
 
Percentage of the requests served within a certain time (ms)
  50%      4
  66%      4
  75%      5
  80%      5
  90%      6
  95%      6
  98%      8
  99%     10
 100%     10 (longest request)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
[root@s15342968 ~]# ab -n 10000 -c 10  "http://florent.clairambault.fr/"
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
 
Benchmarking florent.clairambault.fr (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests
 
 
Server Software:        Apache/2.2.8
Server Hostname:        florent.clairambault.fr
Server Port:            80
 
Document Path:          /
Document Length:        161165 bytes
 
Concurrency Level:      10
Time taken for tests:   7.898135 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1616094683 bytes
HTML transferred:       1612133495 bytes
Requests per second:    1266.12 [#/sec] (mean)
Time per request:       7.898 [ms] (mean)
Time per request:       0.790 [ms] (mean, across all concurrent requests)
Transfer rate:          199821.47 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.9      0       7
Processing:     2    6   1.6      7      13
Waiting:        0    1   1.4      1       8
Total:          2    7   1.5      7      16
 
Percentage of the requests served within a certain time (ms)
  50%      7
  66%      8
  75%      8
  80%      8
  90%      9
  95%     10
  98%     11
  99%     11
 100%     16 (longest request)

WordPress with APC

I updated APC from 3.0 to 3.1 because it totally locked my webserver, it was making it accept HTTP connection but never give any reply.

I had some problem accessing the WordPress 3.0 (latest SVN version) admin interface after that upgrade :

1
Fatal error: Call to undefined function wp_dashboard_setup() in /home/sites/clairambault.fr/florent/wp-admin/index.php on line 15

the bad line is :

1
require_once(ABSPATH . 'wp-admin/includes/dashboard.php');

I just found out here it was because I activated APC with the “apc.include_once_override” option set to 1. If you encounter the same problem, just set it to 0 or change the include by something without the ABSPATH constant like for instance :

1
require_once('./includes/dashboard.php');

Note : requiring local files with “./” makes you save some CPU time.

I personally chose to change the wp-admin/index.php file because I didn’t want to reduce the performance of the other applications (I haven’t done any benchmark of the performance difference though).