Je ne sais pas si cela est vrai, mais quand je lisais la FAQ sur l'un des problèmes de fourniture de sites, j'ai trouvé quelque chose qui a attiré mon attention:
Vérifiez vos méthodes d'entrée / sortie. En C ++, l'utilisation de cin et cout est trop lente. Utilisez-les et vous garantissez de ne pouvoir résoudre aucun problème avec une quantité décente d'entrée ou de sortie. Utilisez plutôt printf et scanf.
Quelqu'un peut-il clarifier cela? Est-ce vraiment plus rapide d' utiliser scanf () dans les programmes C ++ que d'utiliser cin >> quelque chose ? Si oui, est-ce une bonne pratique de l'utiliser dans les programmes C ++? Je pensais que c'était spécifique au C, même si j'apprends juste le C ++ ...
c++
c
performance
io
zeroDivisible
la source
la source
Réponses:
Voici un test rapide d'un cas simple: un programme pour lire une liste de nombres à partir d'une entrée standard et XOR tous les nombres.
version iostream:
version scanf:
Résultats
En utilisant un troisième programme, j'ai généré un fichier texte contenant 33 280 276 nombres aléatoires. Les délais d'exécution sont:
La modification des paramètres d'optimisation du compilateur ne semble pas du tout modifier les résultats.
Donc: il y a vraiment une différence de vitesse.
EDIT: l' utilisateur clyfish souligne ci - dessous que la différence de vitesse est en grande partie due aux fonctions d'E / S iostream maintenant la synchronisation avec les fonctions CI / O. Nous pouvons désactiver cela en appelant à
std::ios::sync_with_stdio(false);
:Nouveaux résultats:
C ++ iostream gagne! Il s'avère que cette synchronisation / vidage interne est ce qui ralentit normalement les entrées / sorties iostream. Si nous ne mélangeons pas stdio et iostream, nous pouvons le désactiver, puis iostream est le plus rapide.
Le code: https://gist.github.com/3845568
la source
iostream
perd lorsque vous analysez plus d'un entier en un seulscanf
appel.http://www.quora.com/Is-cin-cout-slower-than-scanf-printf/answer/Aditya-Vishwakarma
Les performances de
cin
/cout
peuvent être lentes, car elles doivent rester synchronisées avec la bibliothèque C sous-jacente. Ceci est essentiel si C IO et C ++ IO doivent être utilisés.Cependant, si vous n'utilisez que C ++ IO, utilisez simplement la ligne ci-dessous avant toute opération IO.
Pour plus d'informations à ce sujet, consultez la documentation libstdc ++ correspondante .
la source
Scanf est probablement un peu plus rapide que l'utilisation de flux. Bien que les flux fournissent une grande sécurité de type et ne nécessitent pas d'analyser les chaînes de format lors de l'exécution, ils ont généralement l'avantage de ne pas nécessiter d'allocations de mémoire excessives (cela dépend de votre compilateur et de votre runtime). Cela dit, à moins que la performance ne soit votre seul objectif final et que vous soyez dans le chemin critique, vous devriez vraiment privilégier les méthodes les plus sûres (plus lentes).
Il y a un très délicieux article écrit ici par Herb Sutter " Les formateurs de cordes de Manor Farm " qui va dans beaucoup de détails sur les performances des formateurs de cordes comme
sscanf
etlexical_cast
et sur le genre de choses qui les faisaient fonctionner lentement ou rapidement. C'est un peu analogue, probablement au genre de choses qui affectent les performances entre les E / S de style C et le style C ++. La principale différence avec les formateurs était généralement la sécurité du type et le nombre d'allocations de mémoire.la source
Je viens de passer une soirée à travailler sur un problème sur UVa Online (Factovisors, un problème très intéressant, vérifiez-le):
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=35&page=show_problem&problem=1080
J'obtenais TLE (délai dépassé) sur mes soumissions. Sur ces sites de juges en ligne de résolution de problèmes, vous disposez d'un délai d'environ 2 à 3 secondes pour gérer potentiellement des milliers de cas de test utilisés pour évaluer votre solution. Pour les problèmes intensifs en calcul comme celui-ci, chaque microseconde compte.
J'utilisais l'algorithme suggéré (lu dans les forums de discussion du site), mais j'obtenais toujours des TLE.
J'ai changé juste "cin >> n >> m" en "scanf ("% d% d ", & n, & m)" et les quelques petits "couts" en "printfs", et mon TLE est devenu "Accepté"!
Donc, oui, cela peut faire une grande différence, surtout lorsque les délais sont courts.
la source
Si vous vous souciez à la fois des performances et du formatage des chaînes, jetez un œil à la bibliothèque FastFormat de Matthew Wilson .
edit - lien vers la publication accu sur cette bibliothèque: http://accu.org/index.php/journals/1539
la source
Il existe des implémentations stdio ( libio ) qui implémentent FILE * en tant que streambuf C ++, et fprintf en tant qu'analyseur de format d'exécution. Les IOstream n'ont pas besoin d'analyse du format d'exécution, tout est fait au moment de la compilation. Ainsi, avec les backends partagés, il est raisonnable de s'attendre à ce que iostreams soit plus rapide à l'exécution.
la source
Oui, iostream est plus lent que cstdio.
Oui, vous ne devriez probablement pas utiliser cstdio si vous développez en C ++.
Cela dit, il existe des moyens encore plus rapides d'obtenir des E / S que scanf si vous ne vous souciez pas du formatage, de la sécurité de type, bla, bla, bla ...
Par exemple, il s'agit d'une routine personnalisée pour obtenir un nombre de STDIN:
la source
Le problème est que cela
cin
implique beaucoup de frais généraux car cela vous donne une couche d'abstraction auscanf()
- dessus des appels. Vous ne devriez pas utiliserscanf()
overcin
si vous écrivez un logiciel C ++ parce que c'est pour cela que vous voulezcin
. Si vous voulez des performances, vous n'écririez probablement pas d'E / S en C ++ de toute façon.la source
cin
vraiment plus "abstrait" (à l'exécution) quescanf
? Je ne pense pas ...scanf
doit interpréter la chaîne de format au moment de l'exécution, alors que leiostream
connaît le format au moment de la compilation.std::istream
est configuré au moment de l' exécution (via les manipulateurs d'E / S ou en définissant des indicateurs sur l'istream
objet lui-même). UnFILE*
objet en revanche n'a pas un tel état, donc un appel àscanf
cet égard est beaucoup plus stable.Les déclarations
cin
etcout
à usage général semblent être plus lent quescanf
etprintf
en C ++, mais en réalité ils sont plus rapides!La chose est: en C ++, chaque fois que vous utilisez
cin
etcout
, un processus de synchronisation a lieu par défaut qui garantit que si vous utilisez les deuxscanf
etcin
dans votre programme, ils fonctionnent tous les deux de manière synchronisée. Ce processus de synchronisation prend du temps. Par conséquentcin
etcout
SEMBLENT être plus lent.Cependant, si le processus de synchronisation est défini pour ne pas se produire,
cin
est plus rapide quescanf
.Pour ignorer le processus de synchronisation, incluez l'extrait de code suivant dans votre programme au début de
main()
:Visitez ce site pour plus d'informations.
la source
Il y a un bogue à la fin du fichier, mais ce code C est considérablement plus rapide que la version C ++ plus rapide.
Le C ++ d'origine a pris 30 secondes, le code C a pris 2 secondes.
la source
Bien sûr, il est ridicule d'utiliser cstdio sur iostream. Au moins lorsque vous développez un logiciel (si vous utilisez déjà c ++ sur c, allez jusqu'au bout et utilisez ses avantages au lieu de ne souffrir que de ses inconvénients).
Mais dans le juge en ligne, vous ne développez pas de logiciel, vous créez un programme qui devrait être capable de faire des choses que les logiciels Microsoft mettent 60 secondes à réaliser en 3 secondes !!!
Donc, dans ce cas, la règle d'or est la suivante (bien sûr, si vous n'obtenez pas encore plus de problèmes en utilisant java)
la source
Même si
scanf
c'était plus rapide quecin
, cela n'aurait pas d'importance. La grande majorité du temps, vous lirez à partir du disque dur ou du clavier. Obtenir les données brutes dans votre application prend des ordres de grandeur plus de temps qu'il n'en fautscanf
oucin
pour les traiter.la source
iostream
est plus lent que hdd. Oui, ça craint tant que ça.