IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[C#] Probléme de performance avec IsDbNull


Sujet :

Windows Forms

  1. #1
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut [C#] Probléme de performance avec IsDbNull
    J'ai fait un programme qui transfert les données d'un fichier texte via un ODBCDataReader dans une table.
    J'ai trouvé les performances un peu faible. J'ai donc utilisé le profiler qui m'indique que 50% du temps d'exécution de ma méthode est occupée par l'exécution de la méthode IsDbNull.
    Je dois évidement tester IsDbNull pour chaque champ de chaque enregistrement.
    Cette méthode à l'air particulièrement lente. Est-il possible de réaliser le test autrement.

    Actuellement je fait:
    if(!data.IsDBNull(1))
    {
    field1 = data.GetString(1);
    }
    Il semble bien que GetString fonctionne rapidement alors qu'il s'effectue dans 99.99% des cas.

  2. #2
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Points : 2 629
    Points
    2 629
    Par défaut
    Sur quel SGBD?

    tu es obligé d'utiliser ODBC ?

  3. #3
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    Oui, il s'agit de fichier Text de longueur fixe. Je pourrais lire le fichier dans un flux mais l'interêt ici est que je peux utiliser une définition externe (schema.ini). Car si les champs sont toujours les mêmes, selon l'origine de mon fichier les positions des champs peuvent varier

  4. #4
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Points : 2 629
    Points
    2 629
    Par défaut
    Ah je n'avais pas vu tu le dis que c'est pour un fichier Texte dans ton premier message.

    A ta place j'esserai d'éviter l'ODBC quand même. Si tu as l'ordre des colonnes à chaque fichier reçu (dans l'entête par exple) tu peux toujours te faire un algo qui lit bien le fichier.

    Sinon pour l'odbc sur du text, est il vraiment nécéssaire de tester si un enrgistrement peut être null? Si l'enregistrement est vide, as tu une chaine vide ou dbnull? C'est facile à tester ça non ?

  5. #5
    Expert éminent
    Avatar de neo.51
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    2 663
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 663
    Points : 6 418
    Points
    6 418
    Par défaut
    Comme abel, je pense que c'est le IsDbNull du reader du provider ODBC qui patinne...

    ODBC n'a jamais été une référence en terme de perfs

  6. #6
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    IsDbNull doit être testé car assez bizarement si le champ contient uniquement des espace, l'ODBC le considère comme null et provoque une exception sut GetString. Il ne me reste donc plus qu'a tout réécrire.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut Re: [C#] Probléme de performance avec IsDbNull
    Citation Envoyé par jab
    if(!data.IsDBNull(1))
    {
    field1 = data.GetString(1);
    }
    Et si tu essayes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    object toto = data[1];
    if ( !DBNull.Value.Equals( toto ) )
      field1 = Convert.ToString( toto );
    ?

    Plus rien n'est demandé au reader, à part la valeur 'brute'. Si le problème de perfs vient du reader, la différence devrait se voir avec ça.

  8. #8
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    J'avais pensé à la même chose ou prseque.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    o = data.GetValue(nChamp);
    if ( !DBNull.Value.Equals(o) )
    {
          cS1 = (string)o;
    }
    J'ai fait les tes mais pas de différence significative.

    Je suis occupé à faire des tests pour trouver la réponse. J'ai mis tout les champs en commentaire et tout les traitement de contrôle sur les données aussi pour qu'il reste un minimum. Les choses se présente comme ceci (en gros)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    while (data.Read())
    {
       if (data.IsDBNull(38))
       {
          ...
       }else{
           o = data.GetValue(1);
           if (!DBNull.Value.Equals(o))
           {
               field1 = (string)o;
           }
       }
    }
    Le programme met 120 secondes.

    Si je le change comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    while (data.Read())
    {
       o = data.GetValue(38);
       if (false)
       {
          ...
       }else{
           o = data.GetValue(1);
           if (!DBNull.Value.Equals(o))
           {
               field1 = (string)o;
           }
       }
    }
    Il met approximativement le même temps et c'est également le même temps si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while (data.Read())
    {
       if (data.IsDBNull(38))
       {
          ...
       }else{
           if (data.IsDBNull(1))
           {
               field1 = data.GetString(1);
           }
       }
    }
    Ce qui tend à dire que si le profiler donne 50% du temps à IsDBNull, le fait de l'enlever reporte le traitement de lecture sur l'instruction suivante et le problème reste entier.

    Bizarement, si je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while (data.Read())
    {
       if (false)
       {
          ...
       }else{
           if (data.IsDBNull(1))
           {
               field1 = data.GetString(1);
           }
       }
    }
    Je passe de 120 sec à 35 sec ! alors que je ai enlevé moins de la moitié du traitement.

  9. #9
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    IsDbNull n'est en définitive pas en cause. C'est la première méthode sur un champ qui provoque sa lecture. Donc si on fait un IsDbNull, il semble lent en regard du GetString. Mais si on retire le IsDbNull, c'est le GetString qui du coup est plus lent.

    J'ai pu gagner 25% de perf en utilisant le provider Jet.OLEDB qui permet l'accès aux fichiers textes aussi.

    Merci pour votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de performance avec une regexp
    Par NicoV dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 21/02/2008, 18h46
  2. Réponses: 4
    Dernier message: 03/05/2007, 19h02
  3. Réponses: 7
    Dernier message: 26/04/2007, 09h11
  4. Réponses: 8
    Dernier message: 11/02/2006, 23h36
  5. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo