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

SQLite Discussion :

Optimisation du temps d'execution en C


Sujet :

SQLite

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 6
    Par défaut Optimisation du temps d'execution en C
    Bonjour,
    Je cherche en ce moment un moyen d'optimiser mon code pour que le temps de traitement soit le plus rapide possible. Les diverses insertions qui se trouvent dans mon code sont de cette forme :
    if(sqlite3_prepare_v2(db,"INSERT INTO fl3 values(?, ?, ?, ?, ?);",50,&stmt,NULL)!=SQLITE_OK)
    {
    /* Affiche l'état de chaque requete */
    if(warnmsg) step(sqlite3_step(stmt));
    if(warnmsg) sqlite3_reset(stmt);
    affichage_erreur(errmsg, "write_fl3");
    sqlite3_free(errmsg);
    return -1;
    }else {
    sqlite3_bind_text(stmt, 1, badge, 8, NULL);
    sqlite3_bind_text(stmt, 2, dt, 14, NULL);
    sqlite3_bind_text(stmt, 3, heure1, 14, NULL);
    sqlite3_bind_text(stmt, 4, heure2, 14, NULL);
    sqlite3_bind_text(stmt, 5, heure3, 14, NULL);

    if(warnmsg) step(sqlite3_step(stmt));
    if(warnmsg) sqlite3_reset(stmt);
    sqlite3_free(errmsg);
    return 0;
    }
    L'exécution de mon programme complet met a peu prés 500ms a s'opérer hors j'ai plusieurs clients simultanées et au final quand je fork() pour faire un benchmark avec mon programme sa commence a faire long. En gros 6 secondes pour 10 clients. La notion de vitesse est très importante dans ce que je réalise. J'ai vu que je pouvais utiliser ceci sqlite3_exec(db,"BEGIN;",0,0,&errmsg); en début et sqlite3_exec(db,"END;",0,0,&errmsg); en fin de requête. Cela permet de bien diminuer le temps d'exécution mais seulement si l'on compte faire 5000 enregistrements avec une requete sql par exemple.
    Y a t'il une manière plus rapide en SQLITE3 de faire des insertions et lecture sur une table ? Une façon d'optimiser mon code plus haut ?
    Merci pour vos réponses

  2. #2
    Membre expérimenté

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Par défaut
    Bonjour xinu666,

    Je répond un peu vite à ta question avec peut être une grosse incompréhension de ma part. Voici ce que j'ai compris :

    Tu prépares une requête paramétrée, puis lorsqu'elle est prête, tu lui donnes les paramètres un à un.
    Comme c'est une requête d'insertion, je ne comprend pas l'utilité de faire de la sorte. Je suppose que tu as une explication, mais dans le cas contraire, pourquoi ne pas tout simplement exécuter une requête d'insertion ? Tu connais la taille exacte en octet de tes paramètres, donc tu peux très bien utiliser un tampon suffisant pour y préparer la chaine sql. De plus, le begin transaction et le commit peuvent être placé pour un grand nombre de requêtes à la suite mais pour une seule à la fois c'est inutile, comme tu l'as compris. Je les mets dans l'exemple juste pour montrer que c'est faisable.

    Voici un exemple rapide (non testé) :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    char buf[] =  
      "BEGIN TRANSACTION;"
      "INSERT INTO fl3 values("
        "'%%_badge_%%','%%_dt_%%', "
        "'%%_heure1_%%', '%%_heure2_%%', '%%_heure3_%%');"
      "END TRANSACTION;";
    char sql[2048];
     
      // remplacer les parametres 
      strcpy(sql, buf);
      strreplace(sql,"%%_badge_%%", badge);
      strreplace(sql,"%%_dt_%%", dt);
      strreplace(sql,"%%_heure1_%%", heure1);
      strreplace(sql,"%%_heure2_%%", heure2);
      strreplace(sql,"%%_heure3_%%", heure3);
     
    /*
      //note, je ne me souviens plus très bien du comportement de strreplace()
      //c'est à vérifier pour éviter un seg-fault.
      //les %%_ et _%% ne sont là que pour faire joli, éviter les doublons 
      // et au pire c'est aussi une astuce pour réserver de la place 
      // pour insérer les paramètres. 
     
      // ensuite, un truc du genre :
    */
      int rc;
      rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);
      if( rc!=SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
      }

    Oups... strreplace() est une fonction repiquée sur la toile ou au bureau... de toutes façons, on en a tous une plus ou moins identique à celle-ci :

    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
    16
    17
     
    char *strreplace(char *s, const char *s1, const char *s2)
    {
      char *p = strstr(s, s1);
      if (p) {
         int of = p - s;
         int l  = strlen(s);
         int l1 = strlen(s1);
         int l2 = strlen(s2);
         if (l2 > l1)
            s = (char *)realloc(s, strlen(s) + l2 - l1 + 1);
         if (l2 != l1)
            memmove(s + of + l2, s + of + l1, l - of - l1 + 1);
         strncpy(s + of, s2, l2);
         }
      return s;
    }

    A moins que je sois à côté de la plaque.
    Dans ce cas ... sorry,
    a+

  3. #3
    Membre éclairé
    Inscrit en
    Juillet 2006
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 75
    Par défaut
    Pense aussi à utiliser la commande PRAGMA synchronous qui a une incidence sur la vitesse. De mémoire d'après certains tests que j'avais fait on était presque 10x plus rapide en mode OFF... mais faut pas craindre de corrompre la base !

    PRAGMA synchronous;
    PRAGMA synchronous = FULL; (2)
    PRAGMA synchronous = NORMAL; (1)
    PRAGMA synchronous = OFF; (0)

    Query or change the setting of the "synchronous" flag. The first (query) form will return the setting as an integer. When synchronous is FULL (2), the SQLite database engine will pause at critical moments to make sure that data has actually been written to the disk surface before continuing. This ensures that if the operating system crashes or if there is a power failure, the database will be uncorrupted after rebooting. FULL synchronous is very safe, but it is also slow. When synchronous is NORMAL, the SQLite database engine will still pause at the most critical moments, but less often than in FULL mode. There is a very small (though non-zero) chance that a power failure at just the wrong time could corrupt the database in NORMAL mode. But in practice, you are more likely to suffer a catastrophic disk failure or some other unrecoverable hardware fault. With synchronous OFF (0), SQLite continues without pausing as soon as it has handed data off to the operating system. If the application running SQLite crashes, the data will be safe, but the database might become corrupted if the operating system crashes or the computer loses power before that data has been written to the disk surface. On the other hand, some operations are as much as 50 or more times faster with synchronous OFF.

    In SQLite version 2, the default value is NORMAL. For version 3, the default was changed to FULL.

  4. #4
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 6
    Par défaut
    et merci à vous deux,
    Effectivement bigane tu as raison, mon code copier coller et un vestige de mes tests pour des requêtes d'insertions massives et n'a donc plus lieu d'être vu que je ne fais plus de traitement massif de données , je vais donc tenter sur le benchmark ta version en l'adaptant merci de ton aide.
    Par contre, effectivement ce matin je viens de lire un article sur le PRAGMA synchronous a mettre en mode OFF et effectivement cela permet de diminuer le temps d'exécution par 10 , mais deux questions me vienne :
    - Le pragma synchronous mode off ne s'applique t'il pas simplement a des requêtes de type prepare ou prepare_V2, je crois avoir lu sa mais je ne suis pas sur ? (d'ailleurs si quelqu'un sait ce qu'est un pragma car a part exécuter en mode sécurisé je sais pas et je n'ai pas eu le temps de me renseigner )
    - Est ce que la possibilité de corrompre la base est grande à l'origine ou y a t'il des facteurs déterminant exemple lors de traitement en concurrence d'accès ou autres ?
    merci pour toutes vos réponses très intéressantes

  5. #5
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 6
    Par défaut
    Petit up pour dire que le pragma en OFF m'a fait diminuer mon exécution de 50% c'est incroyable et en même temps sa me fait un peu peur, j'ai pas envie de corrompre la base car les données sont importantes quand même lol !
    Je tiens à préciser que le système sur lequel je bosse une fois en place à une petite batterie interne qui permet de le maintenir actif quelques minutes je pense donc que le risque est moindre
    bon j'espère avoir de vos nouvelles à bientôt et bon week-end

Discussions similaires

  1. [AC-97] Optimiser une requête pour diminuer le temps d'execution
    Par Milyshyn76 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 31/05/2010, 13h22
  2. Réponses: 10
    Dernier message: 09/02/2010, 21h08
  3. Optimiser temps d'execution
    Par un passant dans le forum Débuter
    Réponses: 11
    Dernier message: 06/06/2008, 19h03
  4. optimisation de temps d'execution de requête
    Par Smix007 dans le forum SQL
    Réponses: 7
    Dernier message: 21/06/2007, 18h49
  5. Réponses: 14
    Dernier message: 12/05/2006, 09h20

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