title: Why is reading lines from stdin much slower in C++ than Python?
body: <p>I wanted to compare reading lines of string input from stdin using Python and C++ and was shocked to see my C++ code run an order of magnitude slower than the equivalent Python code. Since my C++ is rusty and I'm not yet an expert Pythonista, please tell me if I'm doing something wrong or if I'm misunderstanding something.</p>
  <hr />
  <p>(<strong>TLDR answer:</strong> include the statement: <code>cin.sync_with_stdio(false)</code> or just use <code>fgets</code> instead.</p>
  <p><strong>TLDR results:</strong> scroll all the way down to the bottom of my question and look at the table.)</p>
  <hr />
  <p><strong>C++ code:</strong></p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  #include &lt;time.h&gt;
  
  using namespace std;
  
  int main() {
      string input_line;
      long line_count = 0;
      time_t start = time(NULL);
      int sec;
      int lps;
  
      while (cin) {
          getline(cin, input_line);
          if (!cin.eof())
              line_count++;
      };
  
      sec = (int) time(NULL) - start;
      cerr &lt;&lt; &quot;Read &quot; &lt;&lt; line_count &lt;&lt; &quot; lines in &quot; &lt;&lt; sec &lt;&lt; &quot; seconds.&quot;;
      if (sec &gt; 0) {
          lps = line_count / sec;
          cerr &lt;&lt; &quot; LPS: &quot; &lt;&lt; lps &lt;&lt; endl;
      } else
          cerr &lt;&lt; endl;
      return 0;
  }
  
  // Compiled with:
  // g++ -O3 -o readline_test_cpp foo.cpp
  </code></pre>
  <p><strong>Python Equivalent:</strong></p>
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python
  import time
  import sys
  
  count = 0
  start = time.time()
  
  for line in  sys.stdin:
      count += 1
  
  delta_sec = int(time.time() - start_time)
  if delta_sec &gt;= 0:
      lines_per_sec = int(round(count/delta_sec))
      print(&quot;Read {0} lines in {1} seconds. LPS: {2}&quot;.format(count, delta_sec,
         lines_per_sec))
  </code></pre>
  <p><strong>Here are my results:</strong></p>
  <pre class="lang-none prettyprint-override"><code>$ cat test_lines | ./readline_test_cpp
  Read 5570000 lines in 9 seconds. LPS: 618889
  
  $ cat test_lines | ./readline_test.py
  Read 5570000 lines in 1 seconds. LPS: 5570000
  </code></pre>
  <p><em>I should note that I tried this both under Mac OS X v10.6.8 (Snow Leopard) and Linux 2.6.32 (Red Hat Linux 6.2). The former is a MacBook Pro, and the latter is a very beefy server, not that this is too pertinent.</em></p>
  <pre class="lang-sh prettyprint-override"><code>$ for i in {1..5}; do echo &quot;Test run $i at `date`&quot;; echo -n &quot;CPP:&quot;; cat test_lines | ./readline_test_cpp ; echo -n &quot;Python:&quot;; cat test_lines | ./readline_test.py ; done
  </code></pre>
  <pre class="lang-none prettyprint-override"><code>Test run 1 at Mon Feb 20 21:29:28 EST 2012
  CPP:   Read 5570001 lines in 9 seconds. LPS: 618889
  Python:Read 5570000 lines in 1 seconds. LPS: 5570000
  Test run 2 at Mon Feb 20 21:29:39 EST 2012
  CPP:   Read 5570001 lines in 9 seconds. LPS: 618889
  Python:Read 5570000 lines in 1 seconds. LPS: 5570000
  Test run 3 at Mon Feb 20 21:29:50 EST 2012
  CPP:   Read 5570001 lines in 9 seconds. LPS: 618889
  Python:Read 5570000 lines in 1 seconds. LPS: 5570000
  Test run 4 at Mon Feb 20 21:30:01 EST 2012
  CPP:   Read 5570001 lines in 9 seconds. LPS: 618889
  Python:Read 5570000 lines in 1 seconds. LPS: 5570000
  Test run 5 at Mon Feb 20 21:30:11 EST 2012
  CPP:   Read 5570001 lines in 10 seconds. LPS: 557000
  Python:Read 5570000 lines in  1 seconds. LPS: 5570000
  </code></pre>
  <hr />
  <p>Tiny benchmark addendum and recap</p>
  <p>For completeness, I thought I'd update the read speed for the same file on the same box with the original (synced) C++ code. Again, this is for a 100M line file on a fast disk. Here's the comparison, with several solutions/approaches:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th style="text-align: left;">Implementation</th>
  <th style="text-align: right;">Lines per second</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td style="text-align: left;">python (default)</td>
  <td style="text-align: right;">3,571,428</td>
  </tr>
  <tr>
  <td style="text-align: left;">cin (default/naive)</td>
  <td style="text-align: right;">819,672</td>
  </tr>
  <tr>
  <td style="text-align: left;">cin (no sync)</td>
  <td style="text-align: right;">12,500,000</td>
  </tr>
  <tr>
  <td style="text-align: left;">fgets</td>
  <td style="text-align: right;">14,285,714</td>
  </tr>
  <tr>
  <td style="text-align: left;">wc (not fair comparison)</td>
  <td style="text-align: right;">54,644,808</td>
  </tr>
  </tbody>
  </table>
  </div>