performance - 为什么F#中的printf这么慢?

标签 performance f#

我真的很惊讶F#的printf这么慢。我有许多处理大型数据文件并写出许多CSV文件的C#程序。我最初使用fprintf writer "%s,%d,%f,%f,%f,%s"开始,以为那将是简单且相当有效的。

但是过了一会儿,我对等待文件处理有点烦。 (我有4gb XML文件要经过并从中写出条目。)

当我通过探查器运行应用程序时,我惊讶地发现printf是一种非常慢的方法。

我将代码更改为不使用printf,现在性能提高了很多。 Printf的性能削弱了我的整体应用程序性能。

举个例子,我的原始代码是:

fprintf sectorWriter "\"%s\",%f,%f,%d,%d,\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,\"%s\",%d,%d,%d,%d,%s,%d"
    sector.Label sector.Longitude sector.Latitude sector.RNCId sector.CellId
    siteName sector.Switch sector.Technology (int sector.Azimuth) sector.PrimaryScramblingCode
    (int sector.FrequencyBand) (int sector.Height) sector.PatternName (int sector.Beamwidth) 
    (int sector.ElectricalTilt) (int sector.MechanicalTilt) (int (sector.ElectricalTilt + sector.MechanicalTilt))
    sector.SectorType (int sector.Radius)


我将其更改为以下内容

seq {
    yield sector.Label; yield string sector.Longitude; yield string sector.Latitude; yield string sector.RNCId; yield string sector.CellId; 
    yield siteName; yield sector.Switch; yield sector.Technology; yield string (int sector.Azimuth); yield string sector.PrimaryScramblingCode;
    yield string (int sector.FrequencyBand); yield string (int sector.Height); yield sector.PatternName; yield string (int sector.Beamwidth); 
    yield string (int sector.ElectricalTilt); yield string (int sector.MechanicalTilt); 
    yield string (int (sector.ElectricalTilt + sector.MechanicalTilt));
    yield sector.SectorType; yield string (int sector.Radius)
}
|> writeCSV sectorWriter


辅助功能

let writeDelimited delimiter (writer:TextWriter) (values:seq<string>) =
    values
    |> Seq.fold (fun (s:string) v -> if s.Length = 0 then v else s + delimiter + v) ""
    |> writer.WriteLine

let writeCSV (writer:TextWriter) (values:seq<string>) = writeDelimited "," writer values


我正在写大约30,000行的文件。没什么特别的。

最佳答案

我不确定这有多重要,但是...

检查printf的代码:

https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/printf.fs

我懂了

// The general technique used this file is to interpret
// a format string and use reflection to construct a function value that matches
// the specification of the format string.  


我认为“反射”一词可能回答了这个问题。

printf非常适合编写简单的类型安全的输出,但是如果您想在内部循环中获得出色的性能,则可能需要使用较低级别的.NET API来编写输出。我还没有做自己的基准测试。

关于performance - 为什么F#中的printf这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6248787/

相关文章:

.net - WPF 的 F# 异步事件处理程序类似于 C# 的 async 和 await

f# - fsharp 中的受歧视工会列表

performance - 在 XSLT : xsl:element name ="div" vs. <div> 中寻找更好的性能

mysql - 慢 SELECT ... LIMIT 联合表上没有 WHERE 子句

Android,在列表适配器中有效地加载图像

java - 在这种情况下如何有效地使用线程?

c# - C# 4.0 中用于文件加载的多线程

F# 计算表达式的用法

bash - 如何强制 F# interactive 默认引用 Gtk#?

Azure函数预编译函数,HttpRequestMessage未传递给函数