“的影响是什么?”;如果为false,则为();在计算机语言基准游戏';s F#螺纹圈入口?
计算机语言基准测试游戏包含一行看似无用的代码:“的影响是什么?”;如果为false,则为();在计算机语言基准游戏';s F#螺纹圈入口?,f#,F#,计算机语言基准测试游戏包含一行看似无用的代码:如果为false,那么()。当我注释掉这一行时,程序运行速度要快得多(对于50000000的输入,~2s对~55s),并产生相同的结果。这是怎么回事?为什么这条线在那里?编译器究竟是如何处理看似不可操作的对象的 守则: let ringLength = 503 let cells = Array.zeroCreate ringLength let threads = Array.zeroCreate ringLength let answer =
如果为false,那么()
。当我注释掉这一行时,程序运行速度要快得多(对于50000000的输入,~2s对~55s),并产生相同的结果。这是怎么回事?为什么这条线在那里?编译器究竟是如何处理看似不可操作的对象的
守则:
let ringLength = 503
let cells = Array.zeroCreate ringLength
let threads = Array.zeroCreate ringLength
let answer = ref -1
let createWorker i =
let next = (i+1)%ringLength
async { let value = cells.[i]
if false then ()
match value with
| 0 -> answer := i+1
| _ ->
cells.[next] <- value - 1
return! threads.[next] }
[<EntryPoint>]
let main args =
cells.[0] <- if args.Length>0 then int args.[0] else 50000000
for i in 0..ringLength-1 do
threads.[i]<-createWorker i
let result = Async.StartImmediate(threads.[0])
printfn "%d" !answer
0
let ringLength=503
让单元格=Array.zeroCreate ringLength
让threads=Array.zeroCreate ringLength
让答案=ref-1
让createWorker i=
设next=(i+1)%ringLength
异步{let value=单元格。[i]
如果为false,则()
匹配值
|0->答案:=i+1
| _ ->
单元格。[下一步]如果计算表达式包含If false then()
,则异步工作流的转换方式略有不同。在该行中,它使用async.Combine
。稍微简化的代码如下所示:
async.Delay(fun () ->
value = cells.[i]
async.Combine
( async.Return(if false then ())
async.Delay(fun () ->
match value with (...) ) ))
转换插入了Combine
,因为if
循环完成的(可能)异步计算需要与以下代码组合。现在,如果删除if
,您会得到如下结果:
async.Delay(fun () ->
value = cells.[i]
match value with (...) ) ))
不同之处在于,现在在传递给Delay
的函数中立即完成了更多的工作
编辑:我认为这造成了差异,因为代码使用了Async.startimimediate
而不是Async.Start
,但情况似乎并非如此。事实上,我根本不明白为什么代码使用异步工作流
编辑II.:我不完全确定Mono,但它肯定会在F#interactive中复制-在那里,带有组合的版本大约慢4倍(这是我所期望的,因为函数分配开销).我最初编写了这段代码。我不记得添加这一行的确切原因,但我猜,如果没有它,优化器会做一些我认为不符合基准游戏精神的事情。首先使用异步的原因是为了将尾部调用延续到下一个异步(这就是为什么它的性能比C#mono好得多的原因)。
-Jomo+1是一个权威的答案(比如它),但我很好奇为什么你会故意惩罚基准测试的性能……回想起来,我相信我想炫耀异步,它是不同的合法执行上下文,同时仍然在同一硬件线程上共享延续(采用与Go goroutines类似的使用模式)。如果没有这一行,F#会将整个过程有效地展开成一个while循环。这对于基准测试来说是很不错的,但一旦你尝试将代码用于实际的事情,性能就会下降20倍左右。