Почему printf в F # такой медленный?

Я был очень удивлен тем, насколько медленным работает printf из F #. У меня есть несколько программ C #, которые обрабатывают большие файлы данных и записывают несколько файлов CSV. Первоначально я начал с использования fprintf writer "% s,% d,% f,% f,% f,% s" , думая, что это будет просто и достаточно эффективно.

Однако через некоторое время я было немного надоело ждать обработки файлов. (У меня есть XML-файлы размером 4 ГБ, чтобы просмотреть и записать из них записи.)

Когда я запускал свои приложения через профилировщик, я был поражен, увидев 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 строк. Ничего особенного.

17
задан Nick Randell 6 June 2011 в 20:26
поделиться