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

C Discussion :

fonction sscanf: problème perf


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut fonction sscanf: problème perf
    Voila mon problème
    Je dois ranger dans un tableau des chaines de caractères séparés par des ; dont je connais le nombre d'éléments
    Ex:
    1.0 ; 2.0 ; 3.0 ; 4.0

    Pour l'instant au sein d'une boucle sur le nombre d'élément je fais un
    scanf(Buffer, "%lf", Tableau + i); puis j'avance au prochain ;.

    Cependant desfois j'ai des entrées avec enormemént de données et le nombre de sscanf peut etre enorme ce qui me casse mes performances.
    Mon idée était de faire un truc genre:
    Test[1000000] = "%f ; %f; %f ; %f"
    et sscanf(Buffer, Test, Tableau, Tableau + 1, Tableau + 2, Tableau + 3);
    Mais étant donné la taille variable du nombre d'entrée je ne peux pas faire cela
    Auriez vous une idée pour avoir quelquechose genre:
    sscanf(Buffer, Test, Tableau) ou la il te remplit toutes les cases du tableau
    Merci
    Jonathan

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Une utilisation de strtod ne serait pas plus simple ?

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void) {
        char input[] = "1.0 ; 2.0 ; 3.0 ; 4.0";
        char *p;
        char *end;
     
        p = input;
     
        do {
            double i = strtod(p, &end);
            /* EDIT : inutile printf("%p : %p\n", p, end); */
            if(p == end) {
                /* la conversion a échoué, on teste la caractère suivant */
                ++p;
            } else {
                /* la conversion a réussi, on affiche le résultat */
                printf("%lf: \n", i);
                /* et on passe à la suite.*/
                p = end;
            }
        }while(*end != '\0');
     
        return 0;
    }
    Dernière modification par Invité(e) ; 21/04/2010 à 11h57. Motif: suppression d'une trace inutile

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut
    merci pour la réponse
    Je ne connaissais pas cette fonction
    Je vais regarder ce que tu proposes
    Merci encore

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut
    J'ai donc essayé en me servant de la fonction strtod mais je n'ai aucun gain de performances par rapport au sscanf.
    Auriez vous une autre idée pour aller plus vite ?
    Merci
    J

  5. #5
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    petit article sur une personne qui semble avoir eu le même problème que toi.

    visiblement strtod calcul la longeur totale de la chaine passée en entrée ce qui dans ton cas (100000) peux prendre du temps.

    http://www.ryanjuckett.com/programmi...tof-and-strtod

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut
    Par contre la son truc c'est du C++ et moi je suis en C.
    Je vais voir si je peux améliorer la fonction strtod mais c'est bizarre qu'on ai pas de fonction plus intélligente que scanf dans ce genre de cas
    merci
    J

  7. #7
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    A part cette ligne là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        *ppEnd = const_cast<char*>( pNumberStart + (*ppEnd-buffer) );
    Le reste est compatible avec le C, ou j'ai raté quelque chose, (peu être les const aussi)

  8. #8
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut
    il y aussi isspace

  9. #9
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par parisjohn Voir le message
    il y aussi isspace
    Non, isspace est du C : cf <ctype.h>.

  10. #10
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Citation Envoyé par parisjohn Voir le message
    il y aussi isspace
    Non, pas d'apres ce que je vois dans le man.

    man isspace

    Name

    isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit - character classification routines

    Synopsis

    #include <ctype.h>
    int isalnum(int c);
    int isalpha(int c);
    int isascii(int c);
    int isblank(int c);
    int iscntrl(int c);
    int isdigit(int c);
    int isgraph(int c);
    int islower(int c);
    int isprint(int c);
    int ispunct(int c);
    int isspace(int c);
    int isupper(int c);
    int isxdigit(int c);

    Description
    These functions check whether c, which must have the value of an unsigned char or EOF, falls into a certain character class according to the current locale.

    isalnum()
    checks for an alphanumeric character; it is equivalent to (isalpha(c) || isdigit(c)).
    isalpha()
    checks for an alphabetic character; in the standard "C" locale, it is equivalent to (isupper(c) || islower(c)). In some locales, there may be additional characters for which isalpha() is true--letters which are neither upper case nor lower case.
    isascii()
    checks whether c is a 7-bit unsigned char value that fits into the ASCII character set.
    isblank()
    checks for a blank character; that is, a space or a tab.
    iscntrl()
    checks for a control character.
    isdigit()
    checks for a digit (0 through 9).
    isgraph()
    checks for any printable character except space.
    islower()
    checks for a lower-case character.
    isprint()
    checks for any printable character including space.
    ispunct()
    checks for any printable character which is not a space or an alphanumeric character.
    isspace()
    checks for white-space characters. In the "C""" and "POSIX""" locales, these are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
    isupper()
    checks for an uppercase letter.
    isxdigit()
    checks for a hexadecimal digits, i.e. one of
    0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F.

    Return Value
    The values returned are non-zero if the character c falls into the tested class, and a zero value if not.
    Conforming to
    C99, 4.3BSD. isascii() is a BSD extension and is also an SVr4 extension. isblank() conforms to POSIX.1-2001 and C99 7.4.1.3.
    Note
    The details of what characters belong into which class depend on the current locale. For example, isupper() will not recognize an A-umlaut (:A) as an uppercase letter in the default C locale.

  11. #11
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut
    J'ai testé son code qui comporte 2 fonction C++ ispace et isdigit
    et effectivement ca divise le temps par 3 par rapport a strtod ou sscanf.
    Mais bon c'est du C++, je vais voir si je peux réécrire cela proprement en C
    Mais si vous avez d'autre idée d'optim je suis preneur
    Merci

  12. #12
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Citation Envoyé par parisjohn Voir le message
    J'ai testé son code qui comporte 2 fonction C++ ispace et isdigit
    et effectivement ca divise le temps par 3 par rapport a strtod ou sscanf.
    Mais bon c'est du C++, je vais voir si je peux réécrire cela proprement en C
    Mais si vous avez d'autre idée d'optim je suis preneur
    Merci
    non, isdigit/isspace est dans le standard du language C normé par l'ISO

    Jette un oeil par là:
    http://www.open-std.org/JTC1/sc22/wg...standards.html

    Et plus particulièrement dans le chapitre 7.4.1. de la norme
    http://www.open-std.org/JTC1/sc22/wg...docs/n1124.pdf

    Ensuite un truc qui est dans la norme me parait être suffisamment propre pour ne pas avoir à le refaire.


    D'autres idées:
    Peu être sortir de la boucle avec un break dès que tu as lu le bon nombre d'entrées pour éviter un appel supplémentaire. mais je ne pense pas que cela te fera gagner beaucoup de temps.

    Ensuite je ne sais pas comment arrivent tes lignes et s'il y'a une contrainte d'ordonnancement.

    mais si tu n'en a pas, tu peux penser au multithread pour traiter plusieurs lignes en parallèle.

    le principe serait de créer un certain nombre de thread à l'init de ton application, chaque thread attendrais des donnée sur une queue dédiée.

    Dès qu'une ligne arrive tu selectionne un des threads et tu lui dépose la ligne a analyser dans sa queue.


    Cela va complexifier un peu ton application tu devra gérer des section critiques, etc, Mais si ta machine est multi-coeur tu devrais gagner en temps de traitement, contre une consommation cpu un peu plus élevée.

  13. #13
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 81
    Par défaut
    Ok merci pour les précisions
    Je pensais que c'était du C++ car il faut inlcure #include <cctype> et donc je m'étais trompé en cherchant sur google.
    Je pourrais aussi essayer de le faire sur GPU pendant que j'y suis
    Merci à vous en tout cas

  14. #14
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    après comme on a très peu d'info sur ton application, ce n'est pas évident de donner des conseils liés à l'archi de ton application.

    le conseil multi-thread n'est valable que si tu as d'autres traitements plus lourd que la lecture des données a faire.

Discussions similaires

  1. [RegEx] Fonction preg_match problème
    Par wylls dans le forum Langage
    Réponses: 2
    Dernier message: 13/12/2006, 17h06
  2. Utilisation de la fonction sscanf()
    Par Substantiel dans le forum Langage
    Réponses: 4
    Dernier message: 26/11/2006, 19h40
  3. [Fonction](recursive) Problème pour dresser un arbre
    Par Invité dans le forum Langage
    Réponses: 4
    Dernier message: 21/11/2006, 13h35
  4. Fonction ASP: problème avec popup
    Par claralavraie dans le forum ASP
    Réponses: 6
    Dernier message: 07/02/2006, 10h31
  5. histoire de fonction avec problème sur arguments
    Par bébé dans le forum Langage
    Réponses: 5
    Dernier message: 07/01/2006, 11h29

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