title: tan() computation is two times longer than sin()/cos() with g++ 4.8.2
body: <p>I'm working with algorithms using a large amount of maths functions, and recently we ported the code under g++ 4.8.2 on an Ubuntu system from a Solaris platform.</p>
  
  <p>Surprisingly, some of the algorithms were taking way much time than before. The reason behind is that the <code>std::tan()</code> function is two times longer than doing <code>std::sin()/std::cos()</code>.</p>
  
  <p>Replacing the tan by sin/cos has considerably reduced the computing time for the same results. I wonder why there is such a difference. Is it because of the implementation of the standard library ? Shouldn't the tan function be more effective ?</p>
  
  <p>I wrote a program to check the time of the functions :</p>
  
  <pre><code>#include &lt;cmath&gt;
  #include &lt;iostream&gt;
  #include &lt;chrono&gt;
  
  int main(int argc, char * argv[])
  {
      using namespace std::chrono;
  
      auto start_tan = system_clock::now();
  
      for (int i = 0; i &lt; 50000; ++i)
      {
          const double &amp; a = static_cast&lt;double&gt;(i);
          const double &amp; b = std::tan(a);
      }
  
      auto end_tan = system_clock::now();
      auto elapsed_time_tan = end_tan - start_tan;
      std::cout &lt;&lt; "tan : ";
      std::cout &lt;&lt; elapsed_time_tan.count() &lt;&lt; std::endl;
  
      auto start_sincos = system_clock::now();
  
      for (int i =  0; i &lt; 50000; ++i)
      {
          const double &amp; a = static_cast&lt;double&gt;(i);
          const double &amp; b = std::sin(a) / std::cos(a);
      }
  
      auto end_sincos = system_clock::now();
      auto elapsed_time_sincos = end_sincos - start_sincos;
      std::cout &lt;&lt; "sincos : " &lt;&lt; elapsed_time_sincos.count() &lt;&lt; std::endl;
  
  }
  </code></pre>
  
  <p>And indeed, in the output I have the following time without optimisation :</p>
  
  <pre><code>tan : 8319960
  sincos : 4736988
  </code></pre>
  
  <p>And with optimisation (-O2) :</p>
  
  <pre><code>tan : 294
  sincos : 120
  </code></pre>
  
  <p>If anyone has any idea about this behaviour.</p>
  
  <p><strong><em>EDIT</em></strong></p>
  
  <p>I modified the program according to @Basile Starynkevitch response :</p>
  
  <pre><code>#include &lt;cmath&gt;
  #include &lt;iostream&gt;
  #include &lt;chrono&gt;
  
  int main(int argc, char * argv[])
  {
      using namespace std::chrono;
  
     if (argc != 2) 
     {
        std::cout &lt;&lt; "Need one and only argument : the number of iteration." &lt;&lt; std::endl;
        return 1;
     }
  
     int nb_iter = std::atoi(argv[1]);
     std::cout &lt;&lt; "Number of iteration programmed : " &lt;&lt; nb_iter &lt;&lt; std::endl;
  
  
     double tan_sum = 0.0;
     auto start_tan = system_clock::now();
      for (int i = 0; i &lt; nb_iter; ++i)
      {
          const double &amp; a = static_cast&lt;double&gt;(i);
          const double b = std::tan(a);
        tan_sum += b;
      }
  
      auto end_tan = system_clock::now();
      auto elapsed_time_tan = end_tan - start_tan;
      std::cout &lt;&lt; "tan : " &lt;&lt; elapsed_time_tan.count() &lt;&lt; std::endl;
     std::cout &lt;&lt; "tan sum : " &lt;&lt; tan_sum &lt;&lt; std::endl;
  
     double sincos_sum = 0.0;
      auto start_sincos = system_clock::now();
      for (int i =  0; i &lt; nb_iter; ++i)
      {
          const double &amp; a = static_cast&lt;double&gt;(i);
          const double b = std::sin(a) / std::cos(a);
        sincos_sum += b;
      }
  
      auto end_sincos = system_clock::now();
      auto elapsed_time_sincos = end_sincos - start_sincos;
      std::cout &lt;&lt; "sincos : " &lt;&lt; elapsed_time_sincos.count() &lt;&lt; std::endl;
     std::cout &lt;&lt; "sincos sum : " &lt;&lt; sincos_sum &lt;&lt; std::endl;
  
  }
  </code></pre>
  
  <p>And now as result I get similar time for <code>-O2</code>only :</p>
  
  <pre><code>tan : 8345021
  sincos : 7838740
  </code></pre>
  
  <p>But still the difference with <code>-O2 -mtune=native</code>, but faster indeed :</p>
  
  <pre><code>tan : 5426201
  sincos : 3721938
  </code></pre>
  
  <p>I won't user <code>-ffast-math</code> because I need to keep IEEE compliance.</p>