The following code results in slow1 = 1323 ms
, slow2 = 1311 ms
and fast = 897 ms
. How is that possible?
Here: Nested or not nested if-blocks? they mention that
Any modern compiler, and by that I mean anything built in the past 20 years, will compile these to the same code.
let s = System.Diagnostics.Stopwatch()
let mutable a = 1
s.Start()
for i in 0 .. 1000000000 do
if i < 0 then
if i < 0 then
a <- 4
printfn "fast = %d" s.ElapsedMilliseconds
s.Restart()
for i in 0 .. 1000000000 do
if i < 0 && i < 0 then
a <- 4
printfn "slow1 = %d" s.ElapsedMilliseconds
s.Restart()
for i in 0 .. 1000000000 do
if i < 0 & i < 0 then
a <- 4
printfn "slow2 = %d" s.ElapsedMilliseconds
I've got hold of the MSIL from ildasm, which I'll post here for someone to elaborate on (no time) - it's community wiki time:
Fast (just the i
comparison lines as the rest are identical):
//000030: if i < 1000 then
IL_001f: ldloc.0
IL_0020: ldc.i4 0x3e8
IL_0025: bge.s IL_003b
//000031: if i < 1000 then
IL_0027: ldloc.0
IL_0028: ldc.i4 0x3e8
IL_002d: bge.s IL_0038
Slow:
//000039: if i < 1000 && i < 1000 then
IL_0084: ldloc.0
IL_0085: ldc.i4 0x3e8
IL_008a: bge.s IL_0097
IL_008c: ldloc.0
IL_008d: ldc.i4 0x3e8
IL_0092: clt
IL_0094: nop
IL_0095: br.s IL_0099
IL_0097: ldc.i4.0
IL_0098: nop
IL_0099: brfalse.s IL_00a4
On a side note, C# version of the same has the same timing for both versions.
One thing I noticed in the disassembly was that the F# variables were Program.i and Program.a, so I'm not sure if there's some object interference in F# that isn't there in C#.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With