Desde que F # 2.0 se ha convertido en parte de VS2010, me intereso por F #. Me pregunté de qué serviría. Leí un poco e hice un punto de referencia para medir llamadas de funciones. he utilizado la función de Ackermann :)Realización de llamadas a función .Net (C# F #) VS C++
C#
sealed class Program
{
public static int ackermann(int m, int n)
{
if (m == 0)
return n + 1;
if (m > 0 && n == 0)
{
return ackermann(m - 1, 1);
}
if (m > 0 && n > 0)
{
return ackermann(m - 1, ackermann(m, n - 1));
}
return 0;
}
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("C# ackermann(3,10) = " + Program.ackermann(3, 10));
stopWatch.Stop();
Console.WriteLine("Time required for execution: " + stopWatch.ElapsedMilliseconds + "ms");
Console.ReadLine();
}
}
C++
class Program{
public:
static inline int ackermann(int m, int n)
{
if(m == 0)
return n + 1;
if (m > 0 && n == 0)
{
return ackermann(m - 1, 1);
}
if (m > 0 && n > 0)
{
return ackermann(m - 1, ackermann(m, n - 1));
}
return 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
clock_t start, end;
start = clock();
std::cout << "CPP: ackermann(3,10) = " << Program::ackermann(3, 10) << std::endl;
end = clock();
std::cout << "Time required for execution: " << (end-start) << " ms." << "\n\n";
int i;
std::cin >> i;
return 0;
}
F #
// Ackermann
let rec ackermann m n =
if m = 0 then n + 1
elif m > 0 && n = 0 then ackermann (m - 1) 1
elif m > 0 && n > 0 then ackermann (m - 1) (ackermann m (n - 1))
else 0
open System.Diagnostics;
let stopWatch = Stopwatch.StartNew()
let x = ackermann 3 10
stopWatch.Stop();
printfn "F# ackermann(3,10) = %d" x
printfn "Time required for execution: %f" stopWatch.Elapsed.TotalMilliseconds
Java
public class Main
{
public static int ackermann(int m, int n)
{
if (m==0)
return n + 1;
if (m>0 && n==0)
{
return ackermann(m - 1,1);
}
if (m>0 && n>0)
{
return ackermann(m - 1,ackermann(m,n - 1));
}
return 0;
}
public static void main(String[] args)
{
System.out.println(Main.ackermann(3,10));
}
}
Una continuación
C# = 510ms
C++ = 130 ms
F # = 185ms
Java = Stackoverflow :)
¿Es el poder de F # (excepto pequeña cantidad de código) Si queremos usar .Net y obtener una ejecución un poco más rápida? ¿Puedo optimizar cualquiera de estos códigos (especialmente F #)?
ACTUALIZACIÓN. Me liberé de Console.WriteLine y ejecuté el código C# sin el depurador: C# = 400ms
Ejecute su método una vez antes de ejecutar el punto de referencia. Sus tiempos han incluido el tiempo necesario para JET el idioma intermedio. Además, tome métodos como Console.WriteLine() fuera de su punto de referencia, porque son muy lentos. –
"Ejecute su método una vez antes de ejecutar el punto de referencia. Sus tiempos han incluido el tiempo necesario para JITAR el lenguaje intermedio." ¿Lo es? agrego let dd = ackermann 3 10 y me da 7 ms extra. para C# no cambió :) "Además, tome métodos como Console.WriteLine() fuera de su punto de referencia, porque son muy lentos". Buena idea, pero no se aceleró –
Sí, F # y C# están ambos compilados JIT: ejecuta el método dos veces y usa el segundo punto de referencia. La razón es que el compilador JIT optimiza el código de la máquina para las capacidades específicas de su procesador (CISC, la bondad informática) – Aaronontheweb