title: Optimize a recursive function in Julia
body: <p>I wrote a Julia code which computes integrals over Gaussian functions and I have a sort-of kernel function which is called over and over again.
  According to the Julia built-in <code>Profile</code> Module, this is where I spend most of the time during the actual computation and therefore I would like to see if there is any way in which I can improve it.</p>
  
  <p>It is a recursive function and I implemented it in a kind of straightforward way. As I am not that much used to recursive functions, maybe somebody out there has some ideas/suggestions on how to improve it (both from a purely theoretical algorithmic point of view and/or exploiting special optimizations from the JIT compiler).</p>
  
  <p>Here you have it:</p>
  
  <pre><code>"""Returns the integral of an Hermite Gaussian divided by the Coulomb operator."""
  function Rtuv{T&lt;:Real}(t::Int, u::Int, v::Int, n::Int, p::Real, RPC::Vector{T})
      if t == u == v == 0
          return (-2.0*p)^n * boys(n,p*norm(RPC)^2)
      elseif u == v == 0
          if t &gt; 1
              return  (t-1)*Rtuv(t-2, u, v, n+1, p, RPC) +
                     RPC[1]*Rtuv(t-1, u, v, n+1, p, RPC)
          else
              return RPC[1]*Rtuv(t-1, u, v, n+1, p, RPC)
          end
      elseif v == 0
          if u &gt; 1
              return  (u-1)*Rtuv(t, u-2, v, n+1, p, RPC) +
                     RPC[2]*Rtuv(t, u-1, v, n+1, p, RPC)
          else
              return RPC[2]*Rtuv(t, u-1, v, n+1, p ,RPC)
          end
      else
          if v &gt; 1
              return  (v-1)*Rtuv(t, u, v-2, n+1, p, RPC)
                     RPC[3]*Rtuv(t, u, v-1, n+1, p, RPC)
          else
              return RPC[3]*Rtuv(t, u, v-1, n+1, p, RPC)
          end
      end
  end
  </code></pre>
  
  <p>Don't pay that much attention to the function <code>boys</code>, since according to the profiler it is not that heavy.<br>
  Just to give an idea of the range of numbers: usually the first call comes from <code>t+u+v</code> ranging from <code>0</code> to <code>3</code>, while <code>n</code> always starts at <code>0</code>.</p>
  
  <p>Cheers</p>
  
  <h2>EDIT -- New information</h2>
  
  <p><s>The generated version is slower for small values of <code>t,u,v</code>, I believe the reason is because expressions are not optimzied by the compiler.</s>
  I was benchmarking badly for this case, without interpolating the argument passed. By doing it properly I am always faster with the approach explained in the accepted answer, so hurray!</p>
  
  <p>More generally, does the compiler identify trivial cases such as multiplication by zeros and ones and optimize those away?</p>
  
  <p>Answer to myself: from a quick checking of simple code with <code>@code_llvm</code> it seems not to be the case.</p>