I'm still a bit surprised that that extra jumpq is more expensive than all those extra instructions luajit is executing.
EDIT: For those curious, Lua handles all numbers as floating-point; there are no ints in Lua. That's what all the extra instructions are for. Interestingly it looks like LuaJIT is storing the loop variable x as int (in the eax register) and just converting it to floating-point for comparison against "count" each loop. Interesting bending of the rules there.
So, running under perf stat tells me the luajit version runs very much more instructions (5M vs. 3M with my patched C version), but they run in the same number of cycles (2.5M), with the luajit version using more instructions per cycle. The unpatched C version uses 3.5M instructions, and 3.5M cycles, which is half the number of instructions per cycle compared to the luajit version.
> For those curious, Lua handles all numbers as floating-point; there are no ints in Lua.
Same as in JavaScript. I'm surprised by that. On the surface, having just floats and no ints sounds like a pretty dumb idea. What am I missing? Is there a reasonable rationale for such choice?
Well, doubles can represent all the numbers a 52 bit int can, so there's not a huge reason to not use doubles for whole numbers. It also means that new programmers don't get confused when they do 1/3 and get 1, and the language can be significantly simpler when there's only one number type. Also, when you try to store numbers bigger than 2^52, doubles degrade relatively gracefully, while ints wrap around.
There are definitely downsides too, but it's a trade-off, not an exclusively bad decision.
> Well, doubles can represent all the numbers a 52 bit int can, so there's not a huge reason to not use doubles for whole numbers.
Not exactly.
> It also means that new programmers don't get confused when they do 1/3 and get 1
Is this (actually, getting 0 from 1/3) really more surprising than doing 2+2 and getting 3.9999999999999?
Floats are mostly inexact and introduce errors with almost every operation. It's something you have to constantly keep in mind when doing any kind of math with meaningful comsequences. I for one think that exact types are both more useful for many practical cases, as well as significantly simpler in use.
All floating point integer operations with values smaller than 252 are exact. Most floating point operations with small values with few significant figures are precise.
Fraction, and there are fractions like 1/10 that cannot be represented precisely in base two, much like 1/3 cannot be represented precisely in base 10.
Beyond that, there's the usual issue of pushing out the least significant bits, but that's insurmountable while working in finite precision.
Lua 5.3 introduced actual 64 bit integers but those probably will never get in LuaJIT because its deeply married to the NaN tagging trick, which limits unboxed values to aprox 48 bits.
EDIT: For those curious, Lua handles all numbers as floating-point; there are no ints in Lua. That's what all the extra instructions are for. Interestingly it looks like LuaJIT is storing the loop variable x as int (in the eax register) and just converting it to floating-point for comparison against "count" each loop. Interesting bending of the rules there.