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 :

Lenteur de la commande printf


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 55
    Par défaut Lenteur de la commande printf
    Bonjour à tous et à toutes (ben oui quoi y a aussi des femmes et ce pour notre plus grand plaisir donc ne les oublions pas !),

    Pour ne pas rentrer dans les détails sur mon souci je le contourne par le code suivant :

    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
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
        printf("Patientez calcul en cours !!!\n");
        int nb=0;
        while (nb<1000000000)
        {
            sprintf (stdout,"%d",nb );
        nb++;
        }
        printf("Termine !!!\n");
        return 0;
    }
    Comment faire pour que l'affichage à l'écran soit le plus rapide possible ? en effet que ce soit en c ou c++ les "printf", "cout" et autre "sprintf" ne sont pas des plus rapides... la même boucle sans le "sprintf (stdout,"%d",nb );" dure 1 seconde et celle avec le "sprintf (stdout,"%d",nb );" allonge considérablement les délais.

    Et ne me dites pas "mais pourquoi tu veux afficher l'info à l'écran !!! je veux bien toute les valeurs, ici ce n'est qu'un exemple simplifié !!!!

    Merci d'avance pour votre aide à tous !

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Afficher sur un écran ça prend du temps. Je crois que tu n'as pas vraiment de choix possibles.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 55
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    Afficher sur un écran ça prend du temps. Je crois que tu n'as pas vraiment de choix possibles.
    Tout d'abord merci Nokko34 pour ta réponse...

    En fait y a il tout de même une instruction plus rapide ?

    Et pourquoi est ce si lent ? la commande printf "attendrait" elle que le message soit afficher à l'écran avant de continuer ? dans ce cas y a t il un moyen de "bufferiser" ou éviter d'attendre ce retour ?

    Et juste pour ma gouverne car je n'ai n'en ai pas la maitrise un passage par l'assembleur améliorerait il les temps de réponses ?

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 639
    Par défaut
    Salut,

    Une question sans doute idiote, mais... là, tu va provoquer... 10 milliards d'affichages

    Pourquoi ne pas réduire le nombre d'affichage, pour par exemple, marquer chaque tranche de 100 ou de 1000 (voire des tranches plus grandes ) ?
    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
    int main()
    {
        printf("Patientez calcul en cours !!!\n");
        int nb=0;
        while (nb<1000000000)
        {
            /* le calcul réel */
            if(nb%10000==0) // on rappelle à l'utilisateur que ca fonctionne...
                          // tous les 10 000 calculs
                std::cout<<nb<<" calculs effectués"<<std::endl;
            /* nous pourrions même afficher l'avance sous la forme d'un
             * pourcentage
             if(nb%10000==0)
                 std::cout<<nb/1000000000.0*100 
                          <<" % effectués... Merci de votre patience"<<std::endl;
             */
        nb++;
        }
        printf("Termine !!!\n");
        return 0;
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    188
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 188
    Par défaut
    Bonjour,

    A mon avis c'est surtout dépendant du programme qui affiche ton texte (le terminal sans doute)

    j'ai testé en mettant tout les chiffre dans un string afin de tout affiché a la fin et sa n'est pas plus efficace
    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
     
    #include <iostream>
    #include <QtCore/QString>
     
    using namespace std;
     
    int main(int argc, char** argv)
    {
     
        QString str;
     
        cout << "Patientez calcul en cours !!!" << endl;
        int nb=0;
        while (nb<1000000)
        {
            str.append(QString::number(nb) + "\n");
            nb++;
        }
        cout << str.toStdString();
        cout << "Termine !!!" << endl;
     
        return 0;
    }

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 639
    Par défaut
    @ atttchoum>> Salut, et bienvenue sur le forum.

    Soit cependant attentif à ce que tu utilise...

    De toute évidence, tu te repose sur la bibliothèque Qt.

    Ce n'est pas un mal, loin de là, mais... c'est une bibliothèque qui n'a strictement rien à voir avec le standard, et qui impose des dépendances importantes pour utiliser quelque chose "d'aussi simple" que sa chaine de caractères

    Il est un peu dommage d'imposer ces dépendances quand on sait que le standard C++ fournit plusieurs classes (std::string et les *stringstream pour les conversions éventuelles) qui s'en sortiront très bien
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 55
    Par défaut
    Merci pour toutes vos réponses... bien évidemment koala01 j'avais pensé à utilisé ce "filtrage" pour éviter d'afficher toutes les valeurs... mais si je veux ou dois les afficher que puis je faire ?

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 639
    Par défaut
    Je vais quand même réagir à
    Citation Envoyé par akorx Voir le message
    Tout d'abord merci Nokko34 pour ta réponse...

    En fait y a il tout de même une instruction plus rapide ?
    La réponse est simple: non...
    Et pourquoi est ce si lent ? la commande printf "attendrait" elle que le message soit afficher à l'écran avant de continuer ? dans ce cas y a t il un moyen de "bufferiser" ou éviter d'attendre ce retour ?
    C'est parce que, en fin de compte, les fonctions *printf vont invoquer des fonctions systèmes (propres au système d'exploitation) qui devront (sans doute) lancer une IRQ sur le périphérique d'affichage, attendre d'obtenir cette interruption, envoyer l'information, etc, etc...
    Et juste pour ma gouverne car je n'ai n'en ai pas la maitrise un passage par l'assembleur améliorerait il les temps de réponses ?
    A l'heure actuelle, tu te casserais surement énormément la tête pour pas grand chose: les compilateurs seront très certainement en mesure d'optimiser bien mieux l'appel que tout ce que tu pourrais arriver à faire, surtout si tu n'es pas un "crack" de l'assembleur.

    Il y a de fortes chances pour que tu n'obtienne au mieux que des performances similaires à celle d'un code C (ou C++) si tu mettais les doigts dans l'assembleur
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Citation Envoyé par akorx Voir le message
    dans ce cas y a t il un moyen de "bufferiser" ou éviter d'attendre ce retour ?
    Les affichages sont "nativement bufferisé", /n flush printf et endl flush cout.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 55
    Par défaut
    Donc pour résumer : nos machines, malgré leurs puissances démultipliées années après années, se retrouvent "bêtement" bridés lorsqu'elles doivent afficher le résultat de leur calcul... c'est tout de même un peu frustrant ça quand même, je pensais sincèrement qu'il y avait une solution...

    Merci à chacun d'entre vous pour la richesse de vos réponse en tout cas.

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 639
    Par défaut
    Citation Envoyé par akorx Voir le message
    Donc pour résumer : nos machines, malgré leurs puissances démultipliées années après années, se retrouvent "bêtement" bridés lorsqu'elles doivent afficher le résultat de leur calcul... c'est tout de même un peu frustrant ça quand même, je pensais sincèrement qu'il y avait une solution...

    Merci à chacun d'entre vous pour la richesse de vos réponse en tout cas.
    A vrai dire, il y aurait effectivement une solution pour éviter au moins en partie le problème en utilisant deux tableaux de résultat et deux thread: Le premier thread effectuerait le calcul et remplirait l'un des tableau pendant que le second thread afficherait les résultat contenu dans le deuxième tableau, avec échange des tableaux en temps opportun...

    Mais...

    Le principal problème, c'est que, pour qu'une information apparaissant à l'écran ait la moindre chance d'être saisie et correctement analysée par l'homme qui la regarde, il faut qu'elle soit fixe un bon dizième de seconde (peut être même plus... bien que je n'ai pas les chiffres sous le coude, je dirais volontiers plus proche de 0,25 sec... et je me baserai donc sur cette valeur "arbitraire" par la suite ).

    Le temps nécessaire pour afficher quelque chose avec printf est très largement en deçà de ce délais, car même un dixième de seconde, qui nous parait pourtant si court (essaye de lance et d'arrêter un chrono le plus rapidement possible, généralement, tu y arrivera en un temps de 15 à 25 centièmes de secondes ) est une véritable éternité en terme de "temps ordinateur" au vu de leur puissance actuelle.

    Si donc, pour que tu puisse "profiter" de l'affichage de chaque résultat, tu en viens à devoir ralentir la vitesse de l'affichage, le fait que printf prenne "si longtemps" en terme de "temps ordinateur" ne te pose plus de problème, et, inversement, si le calcul à effectuer est à ce point important que sa seule exécution prend déjà 0,25 seconde, tu as, très certainement des choses bien plus intelligentes à optimiser que cette seule instruction printf.

    Dés lors, si l'on part du principe que, d'une manière ou d'une autre, tu ne pourra d'office pas "profiter" de l'affichage de tous les résultats, et que printf prend, effectivement, un temps très important par rapport au reste, la meilleure solution réside très certainement dans le fait... de ne pas afficher tous les résultat, mais de n'en afficher qu'un sur... un nombre qu'il te faudra déterminer en fonction du traitement effectué

    Au niveau de l'écriture sur disque dur, le problème est un peu différent et vient du fait qu'un disque dur, ca tourne à vitesse constante...

    En considérant même que tu maintiens le fichier ouvert en permanence, il faut prendre en compte le fait que, alors que tu n'écris plus sur le disque pendant le délais nécessaire à ton traitement, le disque dur continue de tourner, et donc que la tête de lecture ne se trouve plus à la bonne position lorsqu'il s'agit de "continuer" l'écriture.

    Le système est donc obligé... d'attendre que le disque dur ait fini son tour (je simplifie énormément, mais le principe est là )

    De plus, chaque secteur du disque dur est capable de contenir... 512 byte, et tu risque donc, en voulant écrire les informations une à une d'être forcé d'attendre que le disque dur fasse deux tours au total pour l'écriture: le premier pour "relire" les bytes déjà écrits sur le secteur prévu à cet effet, le second pour "réécrire" les bytes déjà écrits et... ceux correspondant à la nouvelle valeur à écrire.

    Là aussi, l'utilisation de threads est susceptible d'améliorer les choses, mais, là aussi, l'idéal est donc... de provoquer des écriture par lots plutôt que d'essayer d'écrire les données une à une
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par akorx Voir le message
    Donc pour résumer : nos machines, malgré leurs puissances démultipliées années après années, se retrouvent "bêtement" bridés lorsqu'elles doivent afficher le résultat de leur calcul... c'est tout de même un peu frustrant ça quand même, je pensais sincèrement qu'il y avait une solution...

    Merci à chacun d'entre vous pour la richesse de vos réponse en tout cas.
    Quel intérêt? C'est pas comme si l'oeil/le cerveau humain était capable de suivre. Donc on finit par tout sortir dans un fichier pour pouvoir le lire à notre vitesse...

Discussions similaires

  1. commande printf numérique
    Par vince2005 dans le forum Shell et commandes POSIX
    Réponses: 1
    Dernier message: 20/07/2012, 11h09
  2. Commande printf retour à la ligne non voulu
    Par Rithy666 dans le forum Programmation et administration système
    Réponses: 3
    Dernier message: 05/11/2010, 16h28
  3. commande printf ""
    Par vince2005 dans le forum Unix
    Réponses: 4
    Dernier message: 03/05/2010, 15h31
  4. Incomprhension d'une commande printf avec valeur interdite
    Par NaNaR32 dans le forum Applications et environnements graphiques
    Réponses: 0
    Dernier message: 06/06/2009, 21h00
  5. redirection de la commande printf vers un fichier
    Par carvi dans le forum Langage
    Réponses: 5
    Dernier message: 10/07/2008, 09h56

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