http://stackoverflow.com/questions/11559440/how-to-manage-debug-printing-in-f
It is known that these functions are very slow. Slow enough for most people to avoid them entirely, despite the advantages they offer in verifying argument types.
What I did not know is that these functions are so slow that a few lines of simple user code can speed them up, without changing the interface:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System.Collections.Generic | |
type Cache<'T> private () = | |
static let d = Dictionary<string,'T>() | |
static member Format(format: Printf.StringFormat<'T>) : 'T = | |
let key = format.Value | |
match d.TryGetValue(key) with | |
| true, r -> r | |
| _ -> | |
let r = sprintf format | |
d.Add(key, r) | |
r | |
let sprintf' fmt = | |
Cache<_>.Format(fmt) | |
#time | |
for i in 1 .. 10000 do | |
ignore (sprintf "%i" 15) | |
for i in 1 .. 10000 do | |
ignore (sprintf' "%i" 15) |
With this code I get from 2x to 10x speedups. It is suspicous, I am afraid F# does not cache parsing of the format strings. There is no reason why it should not.
Exercise for the reader: fix the code above to be thread-safe.