2012-10-01 22 views
9

मैं मानक आउटपुट में पाठ मुद्रित करने के विभिन्न तरीकों के बीच अंतर का समय लगा रहा हूं। मैं cout, printf, और ostringstream दोनों \n और std::endl का उपयोग कर परीक्षण कर रहा हूं। (और ऐसा किया) के साथ अंतर बनाने के लिए मुझे std::endl की उम्मीद थी (और ऐसा हुआ), लेकिन मुझे उम्मीद नहीं थी कि यह ostringstream के साथ आउटपुट धीमा कर देगा। मैंने सोचा कि std::endl का उपयोग केवल स्ट्रीम में \n लिख देगा और यह अभी भी एक बार फिर फ्लश हो जाएगा। यहाँ क्या चल रहा है?ostringstream के साथ std :: endl का उपयोग आउटपुट गति को प्रभावित क्यों करता है?

// cout.cpp 
#include <iostream> 

using namespace std; 

int main() { 
    for (int i = 0; i < 10000000; i++) { 
    cout << "Hello World!\n"; 
    } 
    return 0; 
} 

// printf.cpp 
#include <stdio.h> 

int main() { 
    for (int i = 0; i < 10000000; i++) { 
    printf("Hello World!\n"); 
    } 
    return 0; 
} 

// stream.cpp 
#include <iostream> 
#include <sstream> 

using namespace std; 

int main() { 
    ostringstream ss; 
    for (int i = 0; i < 10000000; i++) { 
    ss << "stream" << endl; 
    } 
    cout << ss.str(); 
} 

// streamn.cpp 
#include <iostream> 
#include <sstream> 

using namespace std; 

int main() { 
    ostringstream ss; 
    for (int i = 0; i < 10000000; i++) { 
    ss << "stream\n"; 
    } 
    cout << ss.str(); 
} 

और यहाँ मेरी Makefile

SHELL:=/bin/bash 

all: cout.cpp printf.cpp 
    g++ cout.cpp -o cout.out 
    g++ printf.cpp -o printf.out 
    g++ stream.cpp -o stream.out 
    g++ streamn.cpp -o streamn.out 
time: 
    time ./cout.out > output.txt 
    time ./printf.out > output.txt 
    time ./stream.out > output.txt 
    time ./streamn.out > output.txt 

है यहाँ मैं क्या मिलता है जब मैं make पीछा चलाने से make time

time ./cout.out > output.txt 

real 0m1.771s 
user 0m0.616s 
sys 0m0.148s 
time ./printf.out > output.txt 

real 0m2.411s 
user 0m0.392s 
sys 0m0.172s 
time ./stream.out > output.txt 

real 0m2.048s 
user 0m0.632s 
sys 0m0.220s 
time ./streamn.out > output.txt 

real 0m1.742s 
user 0m0.404s 
sys 0m0.200s 

इन परिणामों संगत कर रहे हैं: यहाँ अपने सभी कोड है।

+0

यह शायद आपके प्रश्न का उत्तर देगा: http://stackoverflow.com/questions/213907/c-stdendl-vs-n संक्षेप में: हाँ, std :: endl आउटपुट – stefan

+2

को फ्लश करता है मुझे नहीं पता कि मैंने पढ़ा है या नहीं यह सवाल गलत है, लेकिन मुझे लगता है कि वह पूछ रहा था कि स्ट्रिंगस्ट्रीम को फ्लश करने का प्रदर्शन मुद्दा क्यों होगा। स्ट्रिंगस्ट्रीम को फ्लश करने के लिए अतिरिक्त काम क्या करता है जिसे कॉल को '.str() 'पर नहीं छोड़ा जा सकता है? 'Cout' के लिए, टर्मिनल को प्रतिपादन में समय लगेगा, क्या स्ट्रिंगस्ट्रीम को फ़्लश करने के कोई दृश्य दुष्प्रभाव हैं? – loganfsmyth

+1

@stefan मैंने वास्तव में उस प्रश्न को पढ़ लिया है, लेकिन कुछ हिस्सों में मैं सोच रहा हूं कि स्ट्रिंगस्ट्रीम को फ़्लश करने का क्या अर्थ है। मैंने सोचा कि यह अनिवार्य रूप से कुछ भी नहीं करेगा, लेकिन स्पष्ट रूप से मैं गलत हूँ। – gsingh2011

उत्तर

14

std::endl स्ट्रीम की एक फ्लश ट्रिगर करता है, जो बहुत प्रिंटिंग धीमा कर देता है। http://en.cppreference.com/w/cpp/io/manip/endl

अक्सर std::endl का उपयोग न करने की अनुशंसा की जाती है जब तक आप वास्तव में स्ट्रीम को फ़्लश नहीं करना चाहते। यदि यह आपके लिए वास्तव में महत्वपूर्ण है, तो आपके उपयोग के मामले पर निर्भर करता है।

flush के बारे में क्यों एक ostringstream पर प्रदर्शन प्रभाव पड़ता है (जहां कोई फ्लशिंग नहीं होनी चाहिए): ऐसा लगता है कि कम से कम संविदा वस्तुओं का निर्माण करने के लिए एक कार्यान्वयन की आवश्यकता है। ostream के good और tie को जांचने की आवश्यकता है। pubsync पर कॉल को अनुकूलित करने में सक्षम होना चाहिए। यह libcpp और libstdC++ के मेरे पढ़ने पर आधारित है।

कुछ और दिलचस्प रोचक प्रश्न पढ़ने के बाद ऐसा लगता है: क्या basic_ostringstream::flush का कार्यान्वयन वास्तव में संविदा ऑब्जेक्ट बनाने के लिए आवश्यक है? यदि नहीं, तो यह मेरे लिए "कार्यान्वयन की गुणवत्ता" मुद्दों की तरह लगता है। लेकिन मुझे वास्तव में लगता है कि इसकी आवश्यकता है क्योंकि basic_stringbug भी badbit सेट में बदल सकता है।

+2

मुझे वास्तव में यह पता था, लेकिन मुझे नहीं पता था कि यह स्ट्रिंगस्ट्रीम के प्रदर्शन को प्रभावित करता है। फ़्लशिंग कोउट का मतलब है कि आउटपुट को बफर में आउटपुट में आउटपुट करना, स्ट्रिंगस्ट्रीम का फ्लशिंग क्या होता है? आउटपुट क्या है कि पाठ को फिसल जाता है? – gsingh2011

+2

@ gsingh2011 यही मुझे लगता है। लेकिन 'basic_ostringstream' वास्तव में' basic_stringbuf' संलग्न है और 'flush' के दस्तावेज़ में उल्लिखित संत्रीकरण का निर्माण करने की आवश्यकता है। – pmr

0

std::endl का उपयोग करते हुए लिख

stream << "\n"; 
stream.flush(); 

std::endl का उपयोग न करें जब तक आप वास्तव में फ्लशिंग ट्रिगर करना चाहते हैं, और/या उत्पादन प्रदर्शन के बारे में परवाह नहीं है के बराबर है।

इसके अलावा, विभिन्न प्लेटफ़ॉर्म पर अलग-अलग लाइन समाप्ति के बारे में चिंता न करें, आपका कार्यान्वयन "\n" का अनुवाद आपके प्लेटफ़ॉर्म के लिए उपयुक्त लाइन पर होगा।

1

एक धारा पर प्रत्येक उत्पादन आपरेशन कई चरणों Dors:

  • यह जाँच करता है, तो धारा अच्छी हालत में है।
  • यह जांचता है कि कुछ अन्य धाराओं को फ़्लश करने की आवश्यकता है या नहीं।
  • वर्णों का अनुक्रम उत्पन्न होता है।
  • यह जांचता है कि लिखित वर्णों के लिए पर्याप्त जगह है या नहीं।
  • endl का उपयोग स्ट्रीम बफर पर अतिरिक्त वर्चुअल फ़ंक्शन कॉल करता है।

मैं व्यक्तिगत रूप से अपेक्षा करता हूं कि अतिरिक्त वर्चुअल फ़ंक्शन कॉल वास्तव में अन्य परिचालनों की तुलना में कम से कम प्रभाव डालती है। आप भी इस उत्पादन की रूपरेखा द्वारा इस अनुमान की पुष्टि कर सकते हैं:

out << "stream" << '\n'; 

... या यहाँ तक कि

out << "stream" << out.widen('\n'); 

यानी, कई सुधार जो एक धारा कार्यान्वयन चेकों को कम करने के आवेदन कर सकते हैं । चाहे यह किया जाता है, निश्चित रूप से कार्यान्वयन पर निर्भर करेगा।

संबंधित मुद्दे