[Mono-dev] Faster

Sebastien Pouliot sebastien.pouliot at gmail.com
Thu Mar 24 12:52:50 EDT 2011


Hola Miguel,

On Thu, 2011-03-24 at 12:00 -0400, Miguel de Icaza wrote:
> Hello guys,
> 
> Today in the shower I had an idea that I believe we could use to
> improve the performance of our class library code.
> 
> Plenty of our class library code has code like this:
> 
> void Foo (Something x)
> {
>     if (x == null)
>         throw new ArgumentNullException ("x");
>     x.DoSomething ();
>     x.AndThenMore ();
> }
> Arguably, if this could be inlined, and the JIT could prove that x is
> not null, we would skip the first test, for example:
> 
> Foo (new Something ());
> 
> But this is the exception, in general, the JIT would not be able to
> know this kind of information for even trivial uses like:
> 
> Foo (Bar.GetSomething ());
> 
> Rendering the optimization not very effective.
> 
> But what if we changed our code in Foo across our class libraries to
> do this instead:
> 
> void Foo (Something x)
> {
>     try {
>         x.DoSomething ();

if DoSomething is an extension method then it may not result in an NRE
and this could have side effects (in DoSomething) or simply throw the
NRE when calling AndThenMore. 

That's not very common in the class lib - but it's growing ;-)

>     } catch (NullReferenceException e){
>         if (x == null)
>              throw new ArgumentNullException ("x");
>         else
>               throw;
>     }
>     x.AndThenMore ();
> }

That pattern affects readability :-( It's not so bad with a single 'x'
but it would quickly get ugly when multiple parameters needs checks (and
not only null checks).

> This has the advantage that the test for the value of "x" being null
> is delayed until we actually need it.    The downside of course is
> that DoSomething could actually take other forms and might end up
> running code that we do not need before it touches x, for example,
> this would be a problem:

Beside the side effects there are also cases where 'x', used as a
parameter, would not throw an NRE in the method being called. E.g. 

string GetKey (object x)
{
	return String.Format ("X: {0}", x);
}

bool IsOk (string x)
{
	return (x == "ok");
}

> // We should never add null values.
> void AddToCache (Something x)
> {
>     cache.Add (x);
> }
> 
> void Foo (Something x)
> {
>       if (x == null)
>           throw new ArgumentNullException ("x");
>       AddToCache (x);
> }
> 
> If we rewrite the above code, we would end up with a bug like the one
> I described.
> 
> Miguel
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list




More information about the Mono-devel-list mailing list