Поскольку F # 2.0 стал частью VS2010, я проявляю интерес к F #. Я задавался вопросом, в чем смысл использовать его. Я читал немного, и я сделал контрольный показатель для измерения вызовов функций. Я использовал функцию Аккермана :)Выполнение вызова функции .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));
}
}
затем
C# = 510ms
C++ = 130ms
F # = 185ms
Java = Stackoverflow :)
Это сила F # (за исключением небольшого количества кода) Если мы хотим использовать .Net и немного ускорить выполнение? Могу ли я оптимизировать любой из этих кодов (особенно F #)?
ОБНОВЛЕНИЕ. Я избавился от Console.WriteLine и запустил код C# без отладчика: C# = 400ms
Выполняйте свой метод один раз перед запуском теста. Ваше время включает время, затраченное на JIT на промежуточном языке. Кроме того, используйте методы, подобные Console.WriteLine() вне вашего теста, потому что они серьезно медленны. –
«Выполняйте свой метод один раз перед запуском теста. Ваше время включило время, затраченное на JIT на промежуточном языке». Не так ли? i add let dd = ackermann 3 10 и дает мне 7 мс дополнительно. для C# не изменилось :) «Также, используйте методы, подобные Console.WriteLine() вне вашего теста, потому что они серьезно медленны». Хорошая идея, но не ускорилась –
Да, F # и C# оба скомпилированы JIT - дважды запустите метод и используйте второй тест. Причина в том, что компилятор JIT оптимизирует машинный код для конкретных возможностей вашего процессора (доброжелательность по CISC) – Aaronontheweb