title: How to optimize ASCII output with QTextStream
body: <p>I'm currently writing out billions of binary records to ASCII files (ugh). I've got things working just fine, but I'd like to optimize the performance if I can. The problem is, the user is allowed to select any number of fields to output, so I can't know at compile-time which of 3-12 fields they'll include. </p>
  
  <p>Is there a faster way to construct lines of ASCII text? As you can see, the types of the fields vary quite a bit and I can't think of a way around the series of if() statements. The output ASCII file has one line per record, so I've tried using a template <a href="http://doc-snapshot.qt-project.org/4.8/qstring.html" rel="nofollow">QString</a> constructed with arg, but that just slowed things down about 15%.</p>
  
  <p>A faster solution doesn't have to use QTextStream, or necessarily write directly to the file, but the output is too large to write the whole thing to memory.</p>
  
  <p>Here's some sample code:</p>
  
  <pre><code>QFile outfile(outpath);
  if(!outfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
  {
      qWarning("Could not open ASCII for writing!");
      return false;
  } else
  {
      /* compute XYZ precision */
      int prec[3] = {0, 0, 0}; //these non-zero values are determined programmatically
  
      /* set up the writer */
      QTextStream out(&amp;outfile);
      out.setRealNumberNotation(QTextStream::FixedNotation);
      out.setRealNumberPrecision(3);
      QString del(config.delimiter); //the user chooses the delimiter character (comma, tab, etc) - using QChar is slower since it has to be promoted to QString anyway
  
      /* write the header line */
      out &lt;&lt; "X" &lt;&lt; del &lt;&lt; "Y" &lt;&lt; del &lt;&lt; "Z";
      if(config.fields &amp; INTFIELD)
          out &lt;&lt; del &lt;&lt; "IntegerField";
      if(config.fields &amp; DBLFIELD)
          out &lt;&lt; del &lt;&lt; "DoubleField";
      if(config.fields &amp; INTFIELD2)
          out &lt;&lt; del &lt;&lt; "IntegerField2";
      if(config.fields &amp; TRIPLEFIELD)
          out &lt;&lt; del &lt;&lt; "Tri1" &lt;&lt; del &lt;&lt; "Tri2" &lt;&lt; del &lt;&lt; "Tri3";
      out &lt;&lt; "\n";
  
      /* write out the points */
      for(quint64 ptnum = 0; ptnum &lt; numpoints; ++ptnum)
      {
          pt = points.at(ptnum);
          out.setRealNumberPrecision(prec[0]);
          out &lt;&lt; pt-&gt;getXYZ(0);
          out.setRealNumberPrecision(prec[1]);
          out &lt;&lt; del &lt;&lt; pt-&gt;getXYZ(1);
          out.setRealNumberPrecision(prec[2]);
          out &lt;&lt; del &lt;&lt; pt-&gt;getXYZ(2);
          out.setRealNumberPrecision(3);
          if(config.fields &amp; INTFIELD)
              out &lt;&lt; del &lt;&lt; pt-&gt;getIntValue();
          if(config.fields &amp; DBLFIELD)
              out &lt;&lt; del &lt;&lt; pt-&gt;getDoubleValue();
          if(config.fields &amp; INTFIELD2)
              out &lt;&lt; del &lt;&lt; pt-&gt;getIntValue2();
          if(config.fields &amp; TRIPLEFIELD)
          {
              out &lt;&lt; del &lt;&lt; pt-&gt;getTriple(0);
              out &lt;&lt; del &lt;&lt; pt-&gt;getTriple(1);
              out &lt;&lt; del &lt;&lt; pt-&gt;getTriple(2);
          }
          out &lt;&lt; "\n";
      } //end for every point
  outfile.close();
  </code></pre>