performance - 列表理解与 List.concat

标签 performance f#

我的(回合制)游戏代码中有以下函数,其中列出了游戏中玩家的所有合法 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/

相关文章:

c++ - std::vector 与 std::array 性能对比

f# - 初学者 : Expressions in F#

用于构建状态和延迟执行的 F# 计算表达式

f# - 在 F# 中将序列包装在流中

java - 优化这个java代码?

java - 在 Java 中生成随机股票行情的最有效方法?

android - 在真实的安卓设备上模拟低内存

性能问题 : Async gRPC with Gunicorn + Tornado

.net - 为什么由 blittable 类型参数化的泛型结构不是非托管类型?

F#:事件模式的高级使用