Q:

¿Porque la recursividad no es eficiente?

Necesito el factorial de 100, me doy cuenta que necesito buscar otra alternativa, podrian ayudar?
public class Main {
    public static void main(String[] args) {        
        System.out.println(factorial(100));
    }

    public static long factorial(long num) {        
        if (num <= 1) 
            return num;

        return num * factorial(num-1);
    }
}

A:

El problema no es la recursividad sino que el valor del factorial de 100 es demasiado grande para entrar en los bits de un long, ya sea en Java u otro lenguaje de programación que maneje este tipo de dato. Nótese que el valor máximo de un long en Java es 0x7fffffffffffffffL o 9223372036854775807
En Java, esto se puede resolver usando BigInteger, aunque reduce el rendimiento de la aplicación.
Ejemplo:
public BigInteger factorial(int n) {
    return (n < 0) ? new BigInteger(String.valueOf(n)) :
        (n == 0 || n == 1) ? BigInteger.ONE :
        new BigInteger(
                String.valueOf(n))
            .multiply( factorial(n-1) );
}

Resultado:
System.out.println(factorial(100));
//imprime 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

A:

El problema de la recursión surge cuando hace cálculos ya calculados previamente, la recursión calcula y repite calculos hasta llegar al caso base.
Mejor lo explico con una imagen, el factorial(3) y el factorial(4) con recursividad:

Segun la imagen, para obtener el factorial(3) se calcula el factorial(2) y factorial(1), luego para obtener el factorial(4) tambien calcula  el factorial(2) y factorial(1), entonces la recursividad repite calculos, eso es muy malo para tiempos de ejecucion.
¿Por qué no guardar los resultados y usarlos cuando necesite? Asi ya no se calcularán una y otra vez, solamente calculas una vez y listo.

El codigo que expongo solamente calcula una vez y va guardandolos,
  para cuando necesite, de esa manera no vuelvo a calcular una y otra
  vez.

import java.util.*;
import java.lang.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        System.out.println(factorial(100));
    }

    public static double  factorial(int  n) {
        double  result[]=new double  [1000] ;          
                result[0] = 1;
                for (int i = 1; i <= n; ++i) {
                    result[i] = i * result[i - 1];
                }
                return result[n];
    }
}

segun comentarios, buenas observaciones!!!:

Iterativo o recursivo el problema que mencionas se daría de todas
  formas y que por cierto no aplica en este caso. De nada sirve
  almacenar los resultados intermedios si luego se van a descartar todos
  excepto el último

import java.util.*;
    import java.lang.*;
    import java.io.*;

    public class Main {
      double  result[]=new double  [1000] ;
      public Main(){
         result[0] = 1;
      }
        public static void main(String[] args) {
            System.out.println(factorial(100));
        }

        public static double  factorial(int  n) {

                    if(!result[n]){
                     for (int i = 1; i <= n; ++i) {
                        result[i] = i * result[i - 1];
                     }
                     return result[n];
                    }else{
                      return result[n];
                    }
        }
    }

