参见英文答案 Why is printf in F# so slow?4个 我正在比较sprintf用法的性能,而且我看到的东西有点困扰.我测试了以下4种方法,将ClassWithToString的实例传递给每个(除了PrintInt,它接收到实际的整数
我正在比较sprintf用法的性能,而且我看到的东西有点困扰.我测试了以下4种方法,将ClassWithToString的实例传递给每个(除了PrintInt,它接收到实际的整数值).
type ClassWithToString() = member this.X = 42 override this.ToString() = this.X.ToString() let Print item : string = sprintf "%A" item let PrintInt item: string = sprintf "%i" item let PrintObj item: string = sprintf "%O" item let Format item : string = System.String.Format("{0}", item)
50,000次迭代的结果:
Print (%A): 3143ms PrintInt (%i): 355ms PrintObj (%O): 384ms Format: 8ms
对于“打印”,我理解%A正在使用反射,因此那里的迟缓并不令人震惊,尽管对于50k次迭代我总是惊讶于总时间.在此之后,“PrintInt”和“PrintObj”不使用反射,因此速度快一个数量级,这也是有意义的.
令我感到困惑的部分是,鉴于String.Format()的结果,sprintf通常看起来非常慢(并且已经在实时应用程序的配置文件中见证过).为什么sprintf幅度比String.Format()慢?我错过了F#空间有更好的选择吗?
Only %A uses reflection. %i would be the base case.
这不是真的.无论您使用哪种说明符,所有printf函数都需要反射以从格式字符串构造类型安全的打印函数.从printf模块看一下this line和this line以获得更多见解.因此很容易理解为什么sprintf“%i”仍然比String.Format慢.
在sprintf“%A”的情况下,它有一个更高级别的反射,这解释了它可怕的缓慢.
Is there a better alternative in the F# space that I’ve missed?
如果您的目的是构建大字符串,那么StringWriter和StringBuilder可能是要走的路.如果您为记录目的进行基准测试,FastPrintf是一个很有前途的库.您可以试用this NuGet package,它声称比内置的printf功能快100倍.