我的(回合制)游戏代码中有以下函数,其中列出了游戏中玩家的所有合法 Action :
let moves game =
let movesType1 game = ... //returns Move list
let movesType2 game = ... //returns Move list
let movesType3 game = ... //returns Move list
List.concat [ (movesType1 game); (movesType2 game); (movesType3 game) ]
现在我想知道如果我使用列表理解和 yield!
执行以下操作会有什么区别:
let moves game =
let movesType1 game = ... //returns Move list
let movesType2 game = ... //returns Move list
let movesType3 game = ... //returns Move list
[ yield! movesType1 game
yield! movesType2 game
yield! movesType3 game ]
在某些情况下我可能会多次使用这个函数,所以我有点担心性能。
最佳答案
这是一个简单的测试脚本,测量两个实现之间的时间差异:
let test1 () = List.concat [ [1..10000]; [1..10000]; [1..10000] ]
let test2 () = [ yield! [1..10000]
yield! [1..10000]
yield! [1..10000] ]
let runTest testImplementation =
for i in 1..1000 do
testImplementation () |> ignore
#time
runTest test1 //Real: 00:00:02.353, CPU: 00:00:02.371, GC gen0: 143, gen1: 96, gen2: 1
#time
System.GC.WaitForFullGCComplete() |> ignore
#time
runTest test2 //Real: 00:00:03.739, CPU: 00:00:03.712, GC gen0: 185, gen1: 185, gen2: 0
#time
看起来 List.concat
更好一点,但是像所有性能方面的事情一样,您应该衡量性能优势是否真的对您的用例很重要。
关于performance - 列表理解与 List.concat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38703651/