问题
I was comparing the performance of sprintf usages and am a little troubled by what I saw. I tested the following 4 methods, passing an instance of ClassWithToString in to each (except for PrintInt, which received the actual integer value).
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)
The results for 50,000 iterations:
Print (%A): 3143ms
PrintInt (%i): 355ms
PrintObj (%O): 384ms
Format: 8ms
For "Print," I understand %A is using reflection so the sluggishness there is not shocking, though for 50k iterations I was surprised at the total time. Following that, "PrintInt" and "PrintObj" do not use reflection and thus are an order of magnitude faster, which also makes sense.
The part that confounds me is that in light of the results of String.Format()
sprintf in general appears to be dreadfully slow (and has been witnessed in profiles of live applications). Why is sprintf magnitudes slower than String.Format()? Is there a better alternative in the F# space that I've missed?
回答1:
Only %A uses reflection. %i would be the base case.
It's not true. All printf
functions need reflection to construct type-safe printing functions from format strings, no matter which specifiers you use. Take a look at this line and this line from printf
module for more insights. So it's easy to see why sprintf "%i"
is still slower than String.Format
.
In the case of sprintf "%A"
, it has one more level of reflection which explains its dreadful slowness.
Is there a better alternative in the F# space that I've missed?
If your purpose is to construct big strings, StringWriter and StringBuilder are probably the ways to go. If you benchmark for logging purpose, FastPrintf is a promising library. You can try out this NuGet package which claims to be 100x faster than the built-in printf
functions.
来源:https://stackoverflow.com/questions/16742189/performance-of-sprintf-vs-string-format