我的(回合制)游戏代码中有以下功能,其中列出了游戏中玩家的所有合法动作:
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 ]
在某些情况下,我可能会多次使用此功能,所以我对性能有点担忧。
答案 0 :(得分:2)
这是一个简单的测试脚本,用于衡量两种实现之间的时序差异:
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
稍微好一些,但是就像所有性能事项一样,您应该测量一下性能优势是否对您的用例有效。