Stupid C++ vs C# performance comparison

I found out that there is a much better test than the 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.
Lot of people think it’s like a java, it has a virtual machine. But in fact it just compiles everything into native language when it accesses methods. This is the whole purpose of the JIT (Just Int Time compiler).

If you feel the JIT compiler is a possible reason of slowness (it slows down the program startup), you can pre-compile your assemblys (mono –aot on linux). If you feel the mono files are a drawback, you can bundle everything in one file using mkbundle. You can read more about this here.

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 in real life usage it doesn’t slow much.

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++.

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).

I haven’t tested this on strings but I’m pretty sure it would be slower in .Net as sizeof(Char) == 2 in C# .Net. It means that each string is two times bigger in C# .Net than in C++.

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 who made 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.

Loading plugins assemblies in .Net

(first post of the year)

This might seem like a quite complex thing to do, but it’s in fact very simple. Thank you .Net for being so well built.

Note : With .Net 3.5, there is a much more advanced method called Add-In. But it’s also much more complex. You should use it on long-term projects with some evolutions of the plugins API (and no possibility to change the plugins). I’ve used it for a project and that really made us lose a lot of time.

So here is the code for a simple plugins class loading system :

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
public List<Type> GetPlugins<T>( string folder ) {
	var files = Directory.GetFiles( folder, "*.dll" );
	var tList = new List<Type>();
	foreach ( string file in files ) {
		try {
			var assembly = Assembly.LoadFile( file );
			foreach ( Type type in assembly.GetTypes() ) {
				if ( !type.IsClass || type.IsNotPublic )
					continue;
				var interfaces = type.GetInterfaces();
				if ( ( (IList) interfaces ).Contains( typeof( T ) ) )
					tList.Add( type );
			}
		}
		catch ( Exception ex ) {
			Logger.LogException( ex );
		}
	}
	return tList;
}
 
public List<T> InstanciatePlugins<T>( List<Type> types, object[] args ) where T:class {
	var list = new List<T>();
 
	foreach ( var t in types )
		if ( ( t.GetInterfaces() as IList ).Contains( typeof( T ) ) )
			list.Add( Activator.CreateInstance( t, args ) as T );
 
	return list;
}

Our project can be organized like this :
Project.Project : The application that will load plugins
Project.Common.Plugins : The common types used by the core and the plugins
Project.Plugin.Test1 : One stupid test plugin

In Project.Common.Plugins, we will declare an interface :

1
2
3
4
5
6
namespace Project.Common.Plugins {
	public interface IPlugin {
		String Name { get; }
		void DoSomeStuff();
	}
}

In Project.Plugin.Test1, we will declare a class :

1
2
3
4
5
6
7
8
9
namespace Project.Plugin.Test1 {
	public class PluginTest1 {
		public String Name { get { return "PluginTest1"; } }
		public void DoSomeStuff() {
			for( int i = 0; i < 100; i++ )
				Console.WriteLine("I only count ({0})", i );
		}
	}
}

This assembly has to be generated in a “plugins” directory.

Then, in your project, you will just have to use the methods given in the beginning and do something like that :

1
2
3
4
5
6
var types = GetPlugins<IPlugin>( "plugins" );
var pluginInstances = InstanciatePlugins( types, null );
 
Console.WriteLine("Plugins are :");
foreach( var pi in pluginInstances )
	Console.WriteLine("* {0}", pi.Name );

If you’re worried that you’re stuck with these created objects, you should take a look on the AppDomain (I think I will talk about them pretty soon). This allows to load .Net assemblies and types and then unload them when ever you want. But as it can be easily adapted to some existing code, you should start without it and then add it when you feel your application could benefit from it.

NDepend

Patrick Smacchia gave me a professional license of NDepend v2.12 so that I could write some stuff about it if I liked it. As it was a gift (yes it is), I decided to force myself to look into this software. And after having looked much of its functionalities, I kind of like it. It’s not THE ultimate tool you have to use, but it’s a little bit like the other (resharper, reflector, etc.), it gives you a better insight of what you have in hand.

It’s a little bit like Resharper, it helps you see what you might have done wrong. Except Resharper tells it when you’re editing the code and NDepend helps you make a full review of the code.

Everything in this software goes around the Code Query Language (CQL). I thought this was some sort of commercial concept to sell more but it turns out that we can do a lot of things with it. It seems like a sensible idea, it’s SQL for the code. And the CQL textbox supports for auto-completion makes the CQL writing process pretty easy.

Don’t make it your judgment tool
I guess the most risky think to do would be to give NDepend to dumb people (like code quality reviewers that don’t understand much of what they do). They would end up getting on everybody’s nevers. Because I don’t think that all the code creating query warnings could be changed. I’ve taken the simple stripped down method example of the StreamRipper app :

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
private static Boolean ParseArgs( String[] args, Parameters parameters ) {
	try {
		for ( int i = 0; i < args.Length; i++ ) {
			switch ( args[ i ] ) {
				case "--url":
				case "-u":
					parameters.Urls.Add( args[ ++i ] );
					break;
 
				case "--user-agent":
				case "-a":
					parameters.UserAgent = args[ ++i ];
					break;
 
				case "--reconnect-attempts":
				case "-r":
					parameters.MaxReconnectionTries = int.Parse( args[ ++i ] );
					break;
			}
		}
		return true;
	}
	catch ( Exception ) {
		Console.Error.WriteLine( "Arguments error ! " );
		return false;
	}
}

This code will create a cyclomatic complexity warning (as it would in Resharper 5.0 [I should talk about this someday] with the cyclomatic complexity addin). So, for me, it’s clear you have to accept to have a lot of warnings. It’s not like resharper where you can solve all the warnings by accepting every little things he tells you to do (sometimes I’m resharper’s slave but I like it).

BUT, if you really want to make it your judgment call tool, you should really stick to this diagram :

You can see that in this project some of the projets are in the zone of pain and the zone of uselessness. Don’t worry. In the zone of uselessness we have the WCF contracts. It’s quite normal they are totally abstract. And close to the zone of pain, we have low level libraries. So, nothing to worry about.

If you WANT a quick and dirty rule : If your business logic core code is in one of these two red zones, you have a problem.

What I think it does well
I think it gives you a quick view of the software you’re working on : What are the main projects, classes and methods. What quality of work you should expect from it. The graphical view isn’t pretty but it gives you a good simplified view :

And anytime you have a doubt, you just double-click on the method and it opens it in Visual Studio.

You have the dependency graphical view :

It doesn’t look very useful like this. But within Visual NDepend, it displays the parent and child assemblies when you move your mouse over a project :

Evolution of your project
NDepend also saves the results of all previous analysis and allows you to show the evolution of your product. You can see easily what methods have been modified / added / deleted from one analysis to an other. Each analysis you do is saved and can be compared to any other later. This can be done on simple .Net assembly. This will allow you to see what has been changed between two version of an assembly. And with the help of reflector, you can see precisely what has been fixed/improved.

You can see a pretty good example by Patrick Smacchia : Comparison of .Net BĂȘta 1 and 2 with NDepend.

My thoughts
I think it gives you a quick and simplified view of the organization and size of a project. It’s great .Net tool, I would recommend to any company having big .Net projects. But you shouldn’t spend too much time on trying to comply with all its default CQL query checks as they are a little bit constrictive. If you do, you might want to increase the threshold values. And please take extra care before making judgment calls (it might be tempting).

.Net, Flex and WebORB.Net

I’ve been working on a project where we had to use Flex on a .Net environment and it had to be realtime. I was a little worried at first that it could be tricky to set up. But with WebORB.Net it’s pretty easy. We used the integrated RTMP (Real Time Messaging Protocol) messaging server. It’s almost like using WCF. The most important differences are that, by default, objects are transmitted as Hashtable and calls can’t be synchronous. We can bind the object to right .Net object within the WebOrb management console but we decided to do it ourself using reflection (because we don’t like to depend too much on the management console).

RTMP
The result is pretty impressive as it makes a really powerful real-time management system. And it’s freaking fast. Like WCF, it can handle concurrent calls. It’s in fact easier because everything is asynchronous but still, it does manage that. These calls are received on parallel threads.

The only problem with WebORB.Net is that you don’t have too much examples in the documentation. Our biggest problem was that we didn’t even knew how to detect what was the current calling connection on a method. This is pretty easy but you can’t exactly guess it. This is a dummy sample to show you how it’s done :

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
public class FlexConnectionsServer:ApplicationAdapter {
	private int _connectionIdCounter = 0;
	private Dictionary<IConnection,int> _connectionsToId = new Dictionary<IConnection,int>();
 
	// Returns the CURRENT connection (must be used from a method called by the flex client)
	private IConnection CurrentConnection { get { return ConnectionHub.getConnectionLocal(); } }
	private int CurrentID { get { return _connectionsToId[ CurrentConnection ]; } }
 
	// When the RTMP service is loaded, we start the time dispatcher thread
	public override bool appStart( IScope app ) {
		new Thread( Thread_TimeDispatcher ).Start();
	}
 
	// This method is called when a client connects
	public override bool appConnect( IConnection conn, object[] parms ) {
		lock ( _connectionsToId ) {
			_connectionsToId.Add( conn, _connectionIdCounter++ );
		}
 
		return true;
	}
 
	// This method is called when a client disconnects
	public override void appDisconnect( IConnection conn ) {
		lock ( _connectionsToId ) {
			_connectionsToId.Remove( conn );
		}
	}
 
	// This is a sample method call
	public String GetMyName() {
		return String.Format( "Client{0}", CurrentId );
	}
 
	// This thread dispatches the current time to every client
	private void Thread_TimeDispatcher() {
		while( true ) {
			var t = DateTime.UtcNow;
			SendCommand( "CurrentTime", new Object[] { t } );
			Thread.Sleep( 1000 );
		}
	}
 
	// Call a remote method on each client connection
	private void SendCommand( String command, Object[] params ) {
		lock ( _connectionsToId ) {
			foreach( var kvp in _connectionsToId )
				( kvp.Key as IServiceCapableConnection ).Invoke( command, params );
		}
	}
}

It’s a little bit like using WCF in Single instance mode.

IIS 7.0 Setup
There was something really weird that happened with my IIS 7.0 on my Windows 7 x64. Using the RTMP connection, I frequently had null return values on .Net method calls. We firstly find a quick way to solve it : Recall each time we get a null value. It’s really dirty, but It worked as a very temporary solution.
Then, when debugging on the IIS process, I noticed a lot of NullReferenceException exceptions displayed on the debugger console. They were about the WebORB “LicenseManager” class, and I had as much exceptions as I had null values on the Flex client. I tried a lot of things that didn’t do anything. And then, I changed the “Managemd pipeline mode” of the Application Pool from “Integrated” to “Classic”, and the problem was solved. The really weird stuff here is that WebORB recommends to use the “Integrated” mode.

MidnightCoders support
We asked MidnightCoders to send us a community edition license, and they instantly answered. We got our license within the 48 hours after our first mail (I was the one slowing it down).

Quick note on the project
To give you a better view of the project I’m talking about :
GPRS Equipment <--(proprietary protocol)--> [Generic M2M Server] <--(WCF)--> [Business logic software] <--(WCF)--> [Flex connections server] <--(RTMP)--> Flex
We’ve got a little equipment (TC65 based as you can guess) that connects to a generic server using our own (real-time and bandwidth optimized) protocol. A business logic software connects to this server using a WCF service. And then we have the WebORB.Net / IIS that connects to this business logic software.

WCF helps make very interesting .Net applications because it simplifies all the communication but can also create deadlocks you might not have seen. Take this example : You have a lock on the WCF Server on the clients list object, you make a call to the WCF client and this client makes a call to the WCF Server that also requires a lock. If you were doing all this client/server calls on the same process this wouldn’t be a problem. But as you use WCF client-to-server and server-to-client calls are made on differents threads. You create a deadlock (unless you set the OperationContract attribute to IsOneWay and/or you fix the deadlock source).

If you’re doing real-time applications, I would recommend to define all the frequently used methods with the “IsOneWay=true” option.

06/11/2009 Update : I added a sample server-to-client code because some people were interested by it.

LinQ to Entities on ADO.Net vs LinQ to SQL

To make it short :

  • LinQ to SQL only works with SQL Server but it’s working great. It’s simple, supports all LinQ operations and optimizes the generated SQL queries.
  • LinQ to Entities on ADO.Net works with lots of database but it doesn’t behave like LinQ to SQL and doesn’t support some key LinQ features.

Now the long story :
For the last project I’ve been working on, we wanted to use LinQ and still be able to switch to one database to an other (MSSQL to MySQL for instance). So we decided we would use LinQ to entity. The generated object are roughly the same, the code to Create/Read/Update/Delete data is roughly the same. So we were quite happy.

Deffered loading
When you do a LinQ request, the data from the associated table isn’t fetched. There’s in fact no other way, as you would get your whole database if you always fetched all the associated objects of your current query.
Deferred loading consists in loading the data coming from an associated table when you request it (when you access your object property).
Eager loading consists in loading the data when you request it.

In LinQ to entities, deferred loading isn’t supported. You have to use eager loading with the .Include(“Property”) LinQ method.

1
var query = from u in Db.User.Include( "Group" ) select u;

But in fact, you can do some deferred loading very easily in LinQ to Entities :

1
2
3
4
5
6
7
8
var query = from u in Db.User select u;
 
foreach( var user in query ) {
    if ( ! user.GroupReference.IsLoaded )     
        user.GroupReference.Load();
 
    Console.WriteLine( "User={0}, Group={1}", user.Name, user.Group.Name );
}

Non supported LinQ key features
Well, now I only want to select the users 1, 2, 3 :

1
2
var users = new int[] { 1, 2, 3 };
var query = from u in Db.User.Include( "Group" ) where users.Contains( u.UserId ) select u;

Oups, that would work on LinQ to SQL, but on LinQ to Entities it doesn’t. LinQ to Entities doesn’t support the .Contains or .Any methods. (Note : these methods are supported since .Net 4.0, see below).

There’s in fact a solution but it requires your request to be typed in a method based LinQ Query :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
		static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(
			Expression<Func<TElement, TValue>> valueSelector,
			IEnumerable<TValue> values
		) {
			if ( null == valueSelector ) { throw new ArgumentNullException( "valueSelector" ); }
			if ( null == values ) { throw new ArgumentNullException( "values" ); }
			ParameterExpression p = valueSelector.Parameters.Single();
			// p => valueSelector(p) == values[0] || valueSelector(p) == ...
			if ( !values.Any() ) {
				return e => false;
			}
			var equals = values.Select( value => (Expression) Expression.Equal( valueSelector.Body, Expression.Constant( value, typeof( TValue ) ) ) );
			var body = equals.Aggregate<Expression>( ( accumulate, equal ) => Expression.Or( accumulate, equal ) );
			return Expression.Lambda<Func<TElement, bool>>( body, p );
		}

And then it looks like this :

1
2
var users = new int[] { 1, 2, 3 };
var query = Db.User.Where( BuildContainsExpression<User, int>( u=> u.UserId, users ) );

Now, let’s say you want to use the Include method in the method based query. Well you can’t. But someone added an extension method to do this :

1
2
3
4
5
	public static class ObjectQueryExtension {
		public static ObjectQuery<T> Include<T>( this ObjectQuery<T> mainQuery, Expression<Func<T, object>> subSelector ) {
			return mainQuery.Include( ( ( subSelector.Body as MemberExpression ).Member as System.Reflection.PropertyInfo ).Name );
		}
	}

You have to use it like that :

1
2
var users = new int[] { 1, 2, 3 };
var query = Db.User.Include( u => u.Group ).Where( BuildContainsExpression<User, int>( u=> u.UserId, users ) );

I hope this could help you start or switch to LinQ to entities in case you hesitated.

LEFT JOIN in LinQ to entities
You know how LEFT JOIN works in LinQ, you need a join and DefaultIfEmpty :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var query = 
from user in Db.User
join preferredSuperHero in Db.User_Parameter on 
	new { 
		UserId = user.UserId, 
		ParamName = "PreferredSuperHero" 
	} 
	equals new { 
		UserId  = preferredSuperHero.UderId, 
		ParamName = preferredSuperHero.Parameter.Name 
	}
	into joinedPreferredSuperHero
from preferredSuperHero in joinedPreferredSuperHero.DefaultIfEmpty()
orderby user.Name
select new { User = user, PreferredSuperHero = preferredSuperHero };

Except… DefaultIfEmpty doesn’t works with LinQ-to-entities. You generally can find other solutions, but it will add some difficulties. (Note : this method is supported since .Net 4.0, see below).

Check what is supported
In this page, you can check if the methods you might require are available. The two non supported methods I talked about are supported with the .Net 4.0 (currently only available in bĂȘta). So most of the problem related to the missing methods will be solved.

About switching from one base to an other
Switching from one base to the other can be pretty easy if you have the right conversion tool. If not, you have to do all the work yourself. If you wish to switch to MySQL for instance, you can use the MySQL conversion tool. It converts the table structure, the keys, the foreign keys, the indexes and the data from MSSQL to MySQL.

After that, the generated code is exactly the same but I’m not sure you can use one EDMX model file for multiple databases. It might work by using an external SSDL (instead of an resource embedded file) that you select in the connection String for each database. But I haven’t tested it yet.

My little conclusion
LinQ to entities works pretty well. The non automatic deferred loading is really not a problem, especially since it totally kills performances (it fetches data row by row instead of loading everything from a single request). My biggest problem was the lacking support of some LinQ methods, you can solve most of them easily (it just makes an ugly code).

With the .Net 3.5, I think the multi-database feature offered by LinQ to Entities on ADO.Net worth this little extra effort to make it work. But if you don’t care about this (because you only build a little short-life program), you should stick to LiNQ to (MS)SQL as everything works instantly on it.

With the .Net 4.0, LinQ to entities becomes even more interesting. And that’s a reason to start using it with the .Net 3.5 framework.

Sources :

Inside Sharepoint

I recently took the time to take a look inside the Microsoft.Sharepoint.dll using reflector. I’m not sure I have the right to do that. And I’m pretty sure I don’t have the right to publish any code extracted from it, so I won’t show any.

Using SPSite(s) and SPWeb(s)
If you do some timing on the SPWeb creation call (SPSite.OpenWeb), you will find out that it’s freaking fast (less then 1 ms on my server). The reason is that the most heavy object, the SPRequest class, is shared among SPWebs of a SPSite. The Dispose call only “Invalidate” the SPWeb, and if this SPWeb is the owner of the SPRequest (which is SPContext.Current.Web object in most of the cases), it releases it.

Personnaly, I like to have something like that when I use a particular SPWeb along my code in a WebPart :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private SPWeb _rootWeb;
public SPWeb RootWeb {
    get {
        if ( _rootWeb == null ) {
            _rootWeb = SPContext.Current.Site.RootWeb;
            if ( _rootWeb != SPContext.Current.Web )
                _toDispose.Add( _rootWeb );  
        }
        return _rootWeb;
    }
}
 
private List<IDisposable> _toDispose = new List<IDisposable>();
protected override void OnUnLoad() {
    foreach( var disp in _toDispose )
        disp.Dispose();
}

But the code above won’t make you gain a 1 ms compared to this code (which is shorter and potentially safer, you don’t need to dispose everything) :

1
2
3
4
5
6
7
8
var rootWeb = SPContext.Current.Site;
try {
    // Your code
}
finally {
     if ( rootWeb != SPContext.Current.Web )
         rootWeb.Dispose();
}

If you had to access some more indirect objects, you certainly should keep the code showed earlier. For instance to use a SuperToken Web :

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
private SPSite _stSite;
SPSite STSite {
    get {
        if ( _stSite == null ) {
            _stSite = new SPSite( SPContext.Current.Site.Url, SPContext.Current.Site.SystemAccount.UserToken );
            if ( _stSite != SPContext.Current.Site )
                _toDispose.Add( _stSite );
        }
        return _stSite;
    }
}
 
private SPWeb _stWeb;
SPWeb STWeb {
    get {
        if ( _stWeb == null ) {
            _stWeb = STSite.OpenWeb( SPContext.Current.Web.Url );
            if ( _stWeb != SPContext.Current.Web )
                _toDispose.Add( _stWeb );
        }
        return _stWeb;
    }
}
 
private List<IDisposable> _toDispose = new List<IDisposable>();
protected override void OnUnLoad() {
    foreach( var disp in _toDispose )
        disp.Dispose();
}

Here, opening these new SPSite and SPWeb takes 200 ms on my server. Making sure this only happen once per webpart (or better, per page) can really boost your performances.

The SPRequest object
Well… I was very disapointed, the SPRequest object references an SPRequestInternalClass from the Microsoft.Sharepoint.Library assembly which only uses interrop COM+ methods. So, it’s basically wrapping COM+ methods. The SPRequest does a lot of exception handling and it keeps track of where (with the stacktrace) it has been created and the size of the “unmanaged stack”.

Optimization
I like how they did their code. It’s pretty optimized (they even use a bunch of gotos). But sometimes there is some weird things and I don’t know if it’s the compiler’s or the developer’s fault. If you look at the code, they have an SPRequestManager.SPRequestsPerThreadWarning property, which gets (in the Registry, at “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings\LocalSPRequestWarnCount”) the max number of opened SPRequest objects opened before logging it (or 8 if this entry doesn’t exist), that takes twice the amount of code it would normaly require.

The limit of disassembling
The most frustrating part is there are tons of really important methods that are obfuscated (and that .Net reflector doesn’t disassemble, it could at least give the IL code in comments). I just have :

1
2
3
private static void xxx() {
    // This item is obfuscated and can not be translated.
}

For instance, I really would have liked to see how works the SPList.Update() method, but it’s also obfuscated.

You should explore it too
In the Microsoft.Office.Server.Search assembly, you will also find some pretty interesting things. If you look how works the standard search webparts, well you will be pretty disapointed. The advanced search uses an internal (in the C# meaning) shared object.

Before doing your own webpart, you should take a look at the overriden methods of some sharepoint webparts. It can show you, for instance, how to create your own toolparts. In my last project, I used a stupid text property instead of using a DropDownList in a ToolPart, I was very disappointed with myself when I discovered this.

Mono Tools for Visual Studio : I have tested it !

Yes, I have tested MonoVS with the version 0.2.2641 (on both client and server). I installed OpenSuse 11.1 and added the MonoVS software repository, and everything worked ! I would have prefer to get it from SVN in order to use it in my Debian hosts but the mono development team seems to have removed it from their SVN repository.

So, the Mono Remote Debugger for Visual Studio works, but there still some bugs. Deployment is super fast and it copies all the required DLL.

Remote debugging can be used (launching it is really fast too), but has some bugs, here are the ones I could find :
- On the classical mouse hover debugging popup, the expandable element “Non-public members” is always empty if available. If not available, every private member is displayed like any other public member variable.
- In my first tests, the “watch” window wouldn’t allow any variable to be expanded.
- If you have a variable not yet declared (but available) in the watch window and try to expand it, debugging just stops without any warning
- Sometimes, when I stop debugging I get a message saying something went wrong and the debugger might be unstable
- Once, after making a pause and then a stop, it totally crashed Visual Studio (but it only happened once).

And this is not really a bug, but unhandled exception are displayed in the dirty popup. This isn’t pretty.

If do “Run remotely in Mono”, it will display the Console output in the server’s console. If you do “Debug remotely in Mono”, the Console output is redirect the Debug output window.

This tool is still in private beta (I guess anyone has a good chance to be accepted like I was), but it can already help a lot of people. Even if you just use the Remote Running (which includes deploying the assembly), it still worth using this tool.