Cette question revient occasionnellement, mais je n'ai pas vu de réponse satisfaisante.
Un modèle typique est (la ligne est un DataRow ):
if (row["value"] != DBNull.Value)
{
someObject.Member = row["value"];
}
Ma première question est de savoir lequel est le plus efficace (j'ai inversé la condition):
row["value"] == DBNull.Value; // Or
row["value"] is DBNull; // Or
row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
Cela indique que .GetType () devrait être plus rapide, mais peut-être que le compilateur connaît quelques astuces que je ne connais pas?
Deuxième question, vaut-il la peine de mettre en cache la valeur de la ligne ["valeur"] ou le compilateur optimise-t-il l'indexeur de toute façon?
Par exemple:
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
Remarques:
- la ligne ["valeur"] existe.
- Je ne connais pas l'index de colonne de la colonne (d'où la recherche de nom de colonne).
- Je pose des questions spécifiquement sur la vérification de DBNull puis sur l'affectation (pas sur l'optimisation prématurée, etc.).
J'ai comparé quelques scénarios (temps en secondes, 10 000 000 essais):
row["value"] == DBNull.Value: 00:00:01.5478995
row["value"] is DBNull: 00:00:01.6306578
row["value"].GetType() == typeof(DBNull): 00:00:02.0138757
Object.ReferenceEquals a les mêmes performances que "=="
Le résultat le plus intéressant? Si vous ne correspondez pas au nom de la colonne par cas (par exemple, "Valeur" au lieu de "valeur", cela prend environ dix fois plus de temps (pour une chaîne):
row["Value"] == DBNull.Value: 00:00:12.2792374
La morale de l'histoire semble être que si vous ne pouvez pas rechercher une colonne par son index, assurez-vous que le nom de la colonne que vous fournissez à l'indexeur correspond exactement au nom de DataColumn.
La mise en cache de la valeur semble également être presque deux fois plus rapide:
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
La méthode la plus efficace semble donc être:
object temp;
string variable;
if (DBNull.Value != (temp = row["value"]))
{
variable = temp.ToString();
}
IDataRecord
extensions.