Précédent   Forum des professionnels en informatique > Bases de données > Autres SGBD > SQLite
SQLite Forum d'entraide SQLite
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 29/04/2008, 13h40   #1
Invité de passage
 
Étudiant
Inscription : février 2008
Messages : 6
Détails du profil
Informations personnelles :
Âge : 30

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2008
Messages : 6
Points : 4
Points : 4
Envoyer un message via MSN à xinu666
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 :
Citation:
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
xinu666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 21h34   #2
Membre actif
 
Inscription : décembre 2004
Messages : 169
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 169
Points : 175
Points : 175
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 :
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 :
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+
bigane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 13h45   #3
Membre du Club
 
Inscription : juillet 2006
Messages : 67
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 67
Points : 51
Points : 51
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 !

Citation:
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.
SERTNM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2008, 09h34   #4
Invité de passage
 
Étudiant
Inscription : février 2008
Messages : 6
Détails du profil
Informations personnelles :
Âge : 30

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2008
Messages : 6
Points : 4
Points : 4
Envoyer un message via MSN à xinu666
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
xinu666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2008, 09h54   #5
Invité de passage
 
Étudiant
Inscription : février 2008
Messages : 6
Détails du profil
Informations personnelles :
Âge : 30

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2008
Messages : 6
Points : 4
Points : 4
Envoyer un message via MSN à xinu666
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
xinu666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h15.


 
 
 
 
Partenaires

Hébergement Web