【问题标题】:a timeit function for F#F# 的 timeit 函数
【发布时间】:2010-01-05 12:10:05
【问题描述】:

我正在尝试写类似的东西

let timeit (x:'a->'b) =
    let start = System.DateTime.Now
    x
    let duration = System.DateTime.Now - start
    printfn "time usage = %A" duration.Milliseconds 
    ()

它适用于

let matrixtest() =
    let x = vector[1.;2.;4.]
    let y = matrix[[1.;2.;4.;];[3.;4.;9.;]]
    printfn "%A" (y * x)
    ()

但不是为了

let rec fib x = 
        match x with
        | 0 | 1 -> 1
        | n -> fib (n-1) + fib (n-2)

sa F# 是静态类型的。

有什么想法吗?谢谢。

【问题讨论】:

    标签: .net f#


    【解决方案1】:

    组合起来

    let timeit f v = 
        let watch = new System.Diagnostics.Stopwatch()
        watch.Start()
        let res = f v 
        watch.Stop()
        printfn "Needed %f ms" (watch.Elapsed.TotalMilliseconds)
        res
    

    【讨论】:

    • 请注意,这适用于任何功能;您可以将其应用于任意代码块,例如:“timeit (fun()->arbitraryBlockOfCode) ()”。也就是说,在 lambda 中包装一段代码以将任意代码传递给函数。
    【解决方案2】:

    使用 System.Diagnostics.Stopwatch

    时间更准确。

    这是假设您得到 0 秒的结果,这不是 DateTime。现在不起作用,只是准确性差。

    http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

    【讨论】:

      【解决方案3】:

      在 F# 交互中测试代码时,您可以使用 #time 指令来为您发送到/输入到 F# 交互中的每段代码计时。示例:

      > #time;;
      
      --> Timing now on
      
      > let slowstring = List.fold (+) "" [for i in 1..10000 -> string i];;
      Real: 00:00:00.544, CPU: 00:00:00.546, GC gen0: 464, gen1: 37, gen2: 0
      
      val slowstring : string =
        "1234567891011121314151617181920212223242526272829303132333435"+[38833 chars]
      
      > let quickstring = String.concat "" [for i in 1..10000 -> string i];;
      Real: 00:00:00.008, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0
      
      val quickstring : string =
        "1234567891011121314151617181920212223242526272829303132333435"+[38833 chars]
      
      > 
      

      【讨论】:

        【解决方案4】:

        即使在矩阵情况下,您也需要将函数应用于一个值。试试这个:

        let timeit f v =
          let start = System.DateTime.Now
          let result = f v
          let duration = System.DateTime.Now - start
          printfn "time usage = %A" duration.Milliseconds 
          result
        

        不过,Aequitarum Custos 使用 StopWatch 类是正确的。

        【讨论】:

        • 为 f 设置两个/更多参数怎么样?
        • 如果参数比较多,可以使用currying:f x y的时间变成'(timeit f x) y',因为(f x)是一个只需要一个y的函数。和 '(timeit g x y) z' 乘以 g x y z 等的计算。
        • 嗯。没有评论编辑。我的意思是 timeit (f x) y。在这种情况下,括号很重要。对不起。
        猜你喜欢
        • 2021-07-21
        • 1970-01-01
        • 1970-01-01
        • 2016-11-30
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 2013-12-20
        • 2013-10-01
        相关资源
        最近更新 更多