净函数调用(C#F#)VS的C ++的性能 [英] Performance of .Net function calling (C# F#) VS C++
问题描述
由于F#2.0已经成为VS2010的一部分,我参加F#的兴趣。我不知道什么是使用它的地步。我读了一下,我做了一个基准来衡量的功能调用。
我已经使用阿克曼的功能:)
Since F# 2.0 has become a part of VS2010 I take an interest in F#. I wondered what's the point of using it. I'd read a bit and I made a benchmark to measure functions calling. I have used Ackermann's function :)
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 ++
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#
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 =#1 :)
An then
C# = 510ms
c++ = 130ms
F# = 185ms
Java = Stackoverflow :)
它是F#的力量(除代码量小),如果我们要使用.Net和获得快一点的执行?我可以optimalize这些代码(尤其是F#)的?
Is it the power of F# (except small amount of code) If we want to use .Net and gain a bit faster execution? Can I optimalize any of these codes (especially F#) ?
更新即可。我摆脱了Console.WriteLine并没有调试器中运行的C#代码:C#= 400毫秒。
UPDATE. I got rid off Console.WriteLine and run the C# code without the debugger: C# = 400ms
推荐答案
我认为,在这种情况下, ,C#和F#之间的差异是由于尾部调用优化。
I believe that in this case, the difference between C# and F# is thanks to tail-call optimization.
一个尾调用是当你有一个为最后一件事做了递归调用在一个功能。在这种情况下,F#实际上并不产生调用指令,而是编译代码进入一个循环(因为调用的是最后一件事,我们可以重用当前堆栈帧,只是跳转到方法的开头) 。
A tail-call is when you have a recursive call that is done as "the last thing" in a function. In this case, F# doesn't actually generate a call instruction, but instead compiles the code into a loop (because the call is the "last thing", we can reuse the current stack frame and just jump to the beginning of the method).
在您的实现的阿克曼
,两人的调用都是尾调用,其中只有一个是没有(在其中执行结果作为参数传递给另一个阿克曼
调用传递)。这意味着,F#版本实际上调用CALL指令(多少?)较少。
In your implementation of ackermann
, two of the calls are tail-calls and only one of them is not (the one where the result is passed as an argument to another ackermann
call). This means that the F# version actually invokes a "call" instruction (much?) less often.
在generall,性能配置是大致相同的C#性能简介。有相关的F#与C#在这里表现相当多的帖子:
In generall, the performance profile is roughly the same as performance profile of C#. There are quite a few posts related to F# vs. C# performance here:
- Is F# really better than C# for math?
这篇关于净函数调用(C#F#)VS的C ++的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!