Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The direct answer is that yes, that's okay.</p> <p>A lot of people have thrown around various ideas of how to improve speed, but there seems to be quite a bit of disagreement over which is most effective. I decided to write a quick test program to get at least some idea of which techniques did what.</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;sstream&gt; #include &lt;time.h&gt; #include &lt;iomanip&gt; #include &lt;algorithm&gt; #include &lt;iterator&gt; #include &lt;stdio.h&gt; char fmt[] = "%s\n"; static const int count = 3000000; static char const *const string = "This is a string."; static std::string s = std::string(string) + "\n"; void show_time(void (*f)(), char const *caption) { clock_t start = clock(); f(); clock_t ticks = clock()-start; std::cerr &lt;&lt; std::setw(30) &lt;&lt; caption &lt;&lt; ": " &lt;&lt; (double)ticks/CLOCKS_PER_SEC &lt;&lt; "\n"; } void use_printf() { for (int i=0; i&lt;count; i++) printf(fmt, string); } void use_puts() { for (int i=0; i&lt;count; i++) puts(string); } void use_cout() { for (int i=0; i&lt;count; i++) std::cout &lt;&lt; string &lt;&lt; "\n"; } void use_cout_unsync() { std::cout.sync_with_stdio(false); for (int i=0; i&lt;count; i++) std::cout &lt;&lt; string &lt;&lt; "\n"; std::cout.sync_with_stdio(true); } void use_stringstream() { std::stringstream temp; for (int i=0; i&lt;count; i++) temp &lt;&lt; string &lt;&lt; "\n"; std::cout &lt;&lt; temp.str(); } void use_endl() { for (int i=0; i&lt;count; i++) std::cout &lt;&lt; string &lt;&lt; std::endl; } void use_fill_n() { std::fill_n(std::ostream_iterator&lt;char const *&gt;(std::cout, "\n"), count, string); } void use_write() { for (int i = 0; i &lt; count; i++) std::cout.write(s.data(), s.size()); } int main() { show_time(use_printf, "Time using printf"); show_time(use_puts, "Time using puts"); show_time(use_cout, "Time using cout (synced)"); show_time(use_cout_unsync, "Time using cout (un-synced)"); show_time(use_stringstream, "Time using stringstream"); show_time(use_endl, "Time using endl"); show_time(use_fill_n, "Time using fill_n"); show_time(use_write, "Time using write"); return 0; } </code></pre> <p>I ran this on Windows after compiling with VC++ 2013 (both x86 and x64 versions). Output from one run (with output redirected to a disk file) looked like this:</p> <pre class="lang-none prettyprint-override"><code> Time using printf: 0.953 Time using puts: 0.567 Time using cout (synced): 0.736 Time using cout (un-synced): 0.714 Time using stringstream: 0.725 Time using endl: 20.097 Time using fill_n: 0.749 Time using write: 0.499 </code></pre> <p>As expected, results vary, but there are a few points I found interesting:</p> <ol><li>printf/puts are much faster than cout when writing to the NUL device</li> <ul><li>but cout keeps up quite nicely when writing to a real file</li></ul> <li>Quite a few proposed optimizations accomplish little <ul><li>In my testing, fill_n is about as fast as anything else</li></ul></li> <li>By far the biggest optimization is avoiding endl</li> <li>cout.write gave the fastest time (though probably not by a significant margin</li></ol> <p>I've recently edited the code to force a call to <code>printf</code>. Anders Kaseorg was kind enough to point out--that <code>g++</code> recognizes the specific sequence <code>printf("%s\n", foo);</code> is equivalent to <code>puts(foo);</code>, and generates code accordingly (i.e., generates code to call <code>puts</code> instead of <code>printf</code>). Moving the format string to a global array, and passing that as the format string produces identical output, but forces it to be produced via <code>printf</code> instead of <code>puts</code>. Of course, it's possible they might optimize around this some day as well, but at least for now (g++ 5.1) a test with <code>g++ -O3 -S</code> confirms that it's actually calling <code>printf</code> (where the previous code compiled to a call to <code>puts</code>).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload