Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与C相比,简单循环上的F代码性能较差-为什么?_C#_.net_Performance_F# - Fatal编程技术网

C# 与C相比,简单循环上的F代码性能较差-为什么?

C# 与C相比,简单循环上的F代码性能较差-为什么?,c#,.net,performance,f#,C#,.net,Performance,F#,我想知道为什么在C#和F#中显然相等的算法之间得到如此不同的结果 F#代码变体: 开放系统 {1I..(bigint(Int32.MaxValue/100))} 设可变和=0I 对于1I中的i..(bigint(Int32.MaxValue/100))do 总和(如下总和) sw.Stop() printfn“占用%A”软件已用 Console.ReadKey()|>忽略 0 完整C#代码(22s): static void Main(字符串[]args) { 秒表sw=新秒表(); sw.S

我想知道为什么在C#和F#中显然相等的算法之间得到如此不同的结果

F#代码变体:

开放系统
{1I..(bigint(Int32.MaxValue/100))}
设可变和=0I
对于1I中的i..(bigint(Int32.MaxValue/100))do
总和(如下总和)
sw.Stop()
printfn“占用%A”软件已用
Console.ReadKey()|>忽略
0
完整C#代码(22s):

static void Main(字符串[]args)
{
秒表sw=新秒表();
sw.Start();
BigInteger总和=新的BigInteger(0);
BigInteger最大值=新的BigInteger(Int32.MaxValue/100);
控制台写入线(最大值);
对于(BigInteger i=新的BigInteger(1);i从

{1I..(bigint(Int32.MaxValue/100))};;
实时:00:00:14.014,CPU:00:00:14.196,GC gen0:1743,gen1:0

设可变t=1I
设可变res=0I
设max=bigint(Int32.MaxValue/100)
而tres这是我能想到的最快/最短的功能版本-它通过使用一系列int来欺骗一些人。它的速度大致与John Palmer在Mono上的版本一样快

{1..(System.Int32.MaxValue/100)} |> Seq.sumBy (fun x -> bigint(x)) |> printfn "%A"
我还制作了John Palmer所做的功能版本,但有一个例外,它在总和中包含最大值,以匹配上述基于序列的版本:

let rec sum (cnt:bigint) (acc:bigint) (max:bigint) =
    if bigint.op_LessThanOrEqual(cnt,max) then
        sum (bigint.op_Increment(cnt)) (acc+cnt) max
    else
        acc

sum 1I 0I (bigint (System.Int32.MaxValue / 100)) |> printfn "%A" 

尝试使用
to
for
循环,而不是
中的
@ildjarn-对于
to
循环,需要
int
类型,但这里我们使用
biginger
,所以这不起作用。@JohnPalmer:啊,抱歉,我没有意识到这一点(我实际上从未在F#:-P中使用
for
).这很奇怪,正如OP中所述,所有3个F#变体在这里产生的速度都完全相同。或者可能我非常需要睡眠。我会再次运行它们。@EnglumeDelysium-我提出了一个新的替代方案,速度要快得多-你的所有版本在我的计算机上花费了大约15秒。你的算法在这里花费了8.8秒。确实更好,但即便如此我希望它能与C版本相匹配:(这太慢了。@EnglumeDelysium-请参阅更新,我得到的F比以前快了大约2倍。编译器正在生成对的调用,而不是特定于类型的运算符(
BigInteger.op_lessthanRequal
),额外的类型注释没有帮助。至少可以说,这是意外的。
let rec sum (cnt:bigint) (acc:bigint) (max:bigint) =
    if bigint.op_LessThanOrEqual(cnt,max) then
        sum (bigint.op_Increment(cnt)) (acc+cnt) max
    else
        acc

sum 1I 0I (bigint (System.Int32.MaxValue / 100)) |> printfn "%A"