C# : Vérifications / Performances
Lorsque que l'on écrit une méthode, il est d' usage de vérifier les paramètres...
mais quelle méthode employez vous ?
la méthode simple, le strict minimum ?
private static void MyMethod1(string a, string b, string c, string d)
{
if (a == null)
throw new ArgumentNullException(string.Format(Properties.Resources.EX_1, "a"), (Exception)null);
if (b == null)
throw new ArgumentNullException(string.Format(Properties.Resources.EX_1, "b"), (Exception)null);
if (c == null)
throw new ArgumentNullException(string.Format(Properties.Resources.EX_1, "c"), (Exception)null);
if (d == null)
throw new ArgumentNullException(string.Format(Properties.Resources.EX_1, "d"), (Exception)null);
}
Ou une méthode plus élégante ? (il y a plus d' informations pour l' appelant lors d' une exception)
private static void MyMethod2(string a, string b, string c, string d)
{
ArgumentNotNull(a, Properties.Resources.EX_1, "a");
ArgumentNotNull(b, Properties.Resources.EX_1, "b");
ArgumentNotNull(c, Properties.Resources.EX_1, "c");
ArgumentNotNull(d, Properties.Resources.EX_1, "d");
}
Check.ArgumentNoNull vaut :
public static void ArgumentNotNull(object obj, string fmt, params object[] args)
{
if (obj == null)
throw new ArgumentNullException(string.Format(fmt, args), (Exception)null);
}
Certes plus élégante, mais elle est malheureusement plus lente à l' exécution. Au premier coup d' oeil, on s' aperçoit qu' à chaque appel, "Properties.Resources.EX_1" est évaluée !
Comparons tout de même :
int nb = 10000;
TimeSpan t1 = DoTest(MyMethod1, nb);
TimeSpan t2 = DoTest(MyMethod2, nb);
Console.WriteLine("t1 : {0}, t2:{1}, t2/t1:{2}", t1, t2, t2.TotalMilliseconds / t1.TotalMilliseconds);
Résultat :
Les chiffres sont petits, mais le nombres d'appels n' est que de 10 000. Le rapport est accablant la deuxième méthode est 86 fois plus lente !!!!!
l' idée ici est gardé un code élégant, tout en se rapprochant des performances de 'MyMethod1'.
Comment évaluer "Properties.Resources.EX_1" uniquement lorsque l' argument est null ?
il suffit de déléguer....
private static void MyMethod2_1(string a, string b, string c, string d)
{
ArgumentNotNull(a, () => ThrowNull(Properties.Resources.EX_1, "a"));
ArgumentNotNull(b, () => ThrowNull(Properties.Resources.EX_1, "b"));
ArgumentNotNull(c, () => ThrowNull(Properties.Resources.EX_1, "c"));
ArgumentNotNull(d, () => ThrowNull(Properties.Resources.EX_1, "d"));
}
public static void ThrowNull(string fmt, params object[] args)
{
throw new ArgumentNullException(string.Format(fmt, args), (Exception)null);
}
public static void ArgumentNotNull(object obj, Action OnNullAction)
{
if (obj == null)
OnNullAction();
}
et en utilisant les méthodes d' extensions on arrive à quelque chose du genre
private static void MyMethod3(string a, string b, string c, string d)
{
a.IsNull(() => ThrowNull(Properties.Resources.EX_1, "a"));
b.IsNull(() => ThrowNull(Properties.Resources.EX_1, "b"));
c.IsNull(() => ThrowNull(Properties.Resources.EX_1, "c"));
d.IsNull(() => ThrowNull(Properties.Resources.EX_1, "d"));
}
et IsNull ressemble beaucoup à ArgumentNotNull
public static void IsNull(this object value, Action OnNullAction)
{
if (value == null)
OnNullAction();
}
on pourrait encore enlever ThrowNull
private static void MyMethod4(string a, string b, string c, string d)
{
a.IsNull(() => Properties.Resources.EX_1, "a");
b.IsNull(() => Properties.Resources.EX_1, "b");
c.IsNull(() => Properties.Resources.EX_1, "c");
d.IsNull(() => Properties.Resources.EX_1, "d");
}
et les performances ???
en conclusion pour 1 000 000 d' appels, la méthode la moins coûteuse dans les plus élégantes, est la méthode 3
private static void MyMethod3(string a, string b, string c, string d)
{
a.IsNull(() => ThrowNull(Properties.Resources.EX_1, "a"));
b.IsNull(() => ThrowNull(Properties.Resources.EX_1, "b"));
c.IsNull(() => ThrowNull(Properties.Resources.EX_1, "c"));
d.IsNull(() => ThrowNull(Properties.Resources.EX_1, "d"));
}
1 000 000 d'appels () :
- Methode 1 : 17.7 ms
- Méthode 3 : 44.2 ms
Contexte du Test :
- Portable Core 2 Duo, 2Ghz, 2Go de RAM
- .Net 3.5 (sans le sp1)
- Windows Vista sp1
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :