title: C++ Program performs better when piped
body: <p>I haven't done any programming in a decade. I wanted to get back into it, so I made this little pointless program as practice. 
  The easiest way to describe what it does is with output of my --help codeblock:</p>
  
  <p>./prng_bench --help</p>
  
  <pre><code>./prng_bench: usage: ./prng_bench $N $B [$T]
  
     This program will generate an N digit base(B) random number until
  all N digits are the same. 
  
  Once a repeating N digit base(B) number is found, the following statistics are displayed:
    -Decimal value of all N digits.
    -Time &amp; number of tries taken to randomly find.
  
  Optionally, this process is repeated T times. 
     When running multiple repititions, averages for all N digit base(B)
  numbers are displayed at the end, as well as total time and total tries.
  </code></pre>
  
  <p>My "problem" is that when the problem is "easy", say a 3 digit base 10 number, and I have it do a large number of passes the "total time" is less when piped to grep. ie:</p>
  
  <p>command ; command |grep took :</p>
  
  <pre><code>./prng_bench 3 10 999999 ; ./prng_bench 3 10 999999|grep took
  
  ....
  Pass# 999999: All 3 base(10) digits =  3 base(10).   Time:    0.00005 secs.   Tries: 23
  It took 191.86701 secs &amp; 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
  An average of 0.00019 secs &amp; 99 tries was needed to find each one. 
  
  It took 159.32355 secs &amp; 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
  </code></pre>
  
  <p>If I run the same command many times w/o grep time is always VERY close.
  I'm using srand(1234) for now, to test. The code between my calls to clock_gettime() for start and stop do not involve any stream manipulation, which would obviously affect time.  I realize this is an exercise in futility, but I'd like to know why it behaves this way.
  Below is heart of the program. Here's a link to the full source on DB if anybody wants to compile and test. <a href="https://www.dropbox.com/s/bczggar2pqzp9g1/prng_bench.cpp" rel="nofollow">https://www.dropbox.com/s/bczggar2pqzp9g1/prng_bench.cpp</a>
  clock_gettime() requires -lrt.</p>
  
  <pre><code>for (int pass_num=1; pass_num&lt;=passes; pass_num++) {   //Executes $passes # of times.
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &amp;temp_time);  //get time
    start_time = timetodouble(temp_time);                //convert time to double, store as start_time
    for(i=1, tries=0; i!=0; tries++) {    //loops until 'comparison for' fully completes. counts reps as 'tries'.  &lt;------------
      for (i=0; i&lt;Ndigits; i++)      //Move forward through array.                                                              |
        results[i]=(rand()%base);    //assign random num of base to element (digit).                                            |
      /*for (i=0; i&lt;Ndigits; i++)     //---Debug Lines---------------                                                           |
        std::cout&lt;&lt;" "&lt;&lt;results[i];   //---a LOT of output.----------                                                           |
      std::cout &lt;&lt; "\n";              //---Comment/decoment to disable/enable.*/   //                                           |
      for (i=Ndigits-1; i&gt;0 &amp;&amp; results[i]==results[0]; i--); //Move through array, != element breaks &amp; i!=0, new digits drawn. -|
    }                                                        //If all are equal i will be 0, nested for condition satisfied.  -|
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &amp;temp_time);  //get time
    draw_time = (timetodouble(temp_time) - start_time);  //convert time to dbl, subtract start_time, set draw_time to diff.
    total_time += draw_time;    //add time for this pass to total.
    total_tries += tries;       //add tries for this pass to total.
    /*Formated output for each pass:
      Pass# ---: All -- base(--) digits = -- base(10)   Time:   ----.---- secs.    Tries: ----- (LINE) */
    std::cout&lt;&lt;"Pass# "&lt;&lt;std::setw(width_pass)&lt;&lt;pass_num&lt;&lt;": All "&lt;&lt;Ndigits&lt;&lt;" base("&lt;&lt;base&lt;&lt;") digits = "
             &lt;&lt;std::setw(width_base)&lt;&lt;results[0]&lt;&lt;" base(10).   Time: "&lt;&lt;std::setw(width_time)&lt;&lt;draw_time
             &lt;&lt;" secs.   Tries: "&lt;&lt;tries&lt;&lt;"\n";
  }
  if(passes==1) return 0;        //No need for totals and averages of 1 pass.
  /* It took ----.---- secs &amp; ------ tries to find --- repeating -- digit base(--) numbers. (LINE)
   An average of ---.---- secs &amp; ---- tries was needed to find each one. (LINE)(LINE) */
   std::cout&lt;&lt;"It took "&lt;&lt;total_time&lt;&lt;" secs &amp; "&lt;&lt;total_tries&lt;&lt;" tries to find "
            &lt;&lt;passes&lt;&lt;" repeating "&lt;&lt;Ndigits&lt;&lt;" digit base("&lt;&lt;base&lt;&lt;") numbers.\n"
            &lt;&lt;"An average of "&lt;&lt;total_time/passes&lt;&lt;" secs &amp; "&lt;&lt;total_tries/passes
            &lt;&lt;" tries was needed to find each one. \n\n";
  return 0;
  </code></pre>