Decimal to Binary function I made

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Decimal to Binary function I made

Post by Positive07 »

bartbes wrote:-snip-

Code: Select all

do
	local conv = {}

	for i = 0, 7 do
		conv[tostring(i)] = ("%i%i%i"):format(i%8/4, i%4/2, i%2/1)
	end

	function tobinary(n)
		return (("%o"):format(n):gsub(".", conv):match("1.+$")) or "0"
	end
end

print(tobinary(4713))
Too much math.floor
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Decimal to Binary function I made

Post by airstruck »

stop the madness
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Decimal to Binary function I made

Post by bartbes »

Positive07 wrote: Too much math.floor
I did wonder if there wasn't a cleaner way.
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Decimal to Binary function I made

Post by Positive07 »

bartbes wrote:
Positive07 wrote: Too much math.floor
I did wonder if there wasn't a cleaner way.
Yeah I just happened to remember there was that %i format, glad I could be useful and thank you for reformatting my code, I had totally forgotten you could do the same with octal
time thief wrote:stop the madness
Yeah we should stop hahaha

Anyway is this method (the string.format + string.gsub) any faster than the loop division methods? I can see it would take slightly more memory because of the look up table but that could be ignored, speed would make the difference but I'm not sure of how slow string.format and gsub are so it could end up being slower
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Decimal to Binary function I made

Post by airstruck »

Positive07 wrote:Anyway is this method (the string.format + string.gsub) any faster than the loop division methods?
Actually it seems to be more than twice as fast. See for yourself: http://pastebin.com/EVmPuTnV

I'm still not sure why a tobinary function is useful, though. I wonder if your approach could be generalized to arbitrary bases somehow?
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Decimal to Binary function I made

Post by Positive07 »

time thief wrote:
Positive07 wrote:Anyway is this method (the string.format + string.gsub) any faster than the loop division methods?
Actually it seems to be more than twice as fast. See for yourself: http://pastebin.com/EVmPuTnV

I'm still not sure why a tobinary function is useful, though. I wonder if your approach could be generalized to arbitrary bases somehow?
Nope, just base 2, 4, 8 (octal), and 16 (hexa), the later two can already be done with the use of string format so the weird one would be base 4, but basically powers of two. For the rest you need to use the division method

And I see that "bartbes" performs better than "Positive and bartbes" when the function is the exact same thing hahaha weird

Also when measuring performance it is better to keep the number of operations static and measure total time (the opposite of what you do) because otherwise the performance of getTime gets in the way and changes the overall result, do this instead:

Code: Select all

local getTime = love.timer.getTime

local perf = function (name)
    collectgarbage()
    print(name)
    local f = toBinary[name]
    local start = getTime()
    for i=1, 100000 do
        f(i)
    end
    local finish = getTime()
    print(('%d ops per second'):format(100000 / (finish - start)))
end
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Decimal to Binary function I made

Post by airstruck »

Positive07 wrote:Also when measuring performance it is better to keep the number of operations static and measure total time (the opposite of what you do) because otherwise the performance of getTime gets in the way and changes the overall result
I don't agree with this. getTime and anything else inside the loop does take time, but it affects all test cases equally. The goal isn't to test how performant any one solution is, but to compare solutions with one another. Other comparative performance testing tools take a similar approach (for example, jsPerf uses a strategy like this). Even if the goal were to measure the performance of each solution independently, tests could be compared against a no-op loop to get a more accurate reading. I prefer this approach because the amount of time the tests take is predictable and long-running scripts can't bog the test harness down indefinitely.
User avatar
slime
Solid Snayke
Posts: 3166
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Decimal to Binary function I made

Post by slime »

love.timer.getTime (and most other love functions) will cause the JIT compiler to avoid compilation of any code "around" it. If calls to getTime are around, but not in, a loop, then the JIT compiler may be able to compile the code in the loop (provided nothing else in the loop prevents it.)
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Decimal to Binary function I made

Post by airstruck »

Ahh, well that changes things. Do you know if using a socket as a timer would also prevent JIT compilation? I've run into cases where a perf will hang a build process if allowed to run for an unknown amount of time, so I'd really rather use this approach when possible.

Thinkng about it more, does that really matter? The JIT doesn't really need to compile the loop, just the function being tested (called from within the loop). I don't care about the performance of the loop, just the function being tested. The performance of the loop can be tested separately and the results can be adjusted for it. I'm not really sure why it would matter whether the stuff in the loop gets compiled. :huh:

I've been running this with LuaJIT's dump.on() and as far as I can tell all of the solutions fall back to the interpreter for various reasons (string.format, table.concat, "inner loop in root trace" and so on). I haven't messed with LuaJIT much before, but it seems to fall back to the interpreter quite a bit. Now I'd like to see a solution to this that can be completely compiled.
User avatar
slime
Solid Snayke
Posts: 3166
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Decimal to Binary function I made

Post by slime »

time thief wrote:Ahh, well that changes things. Do you know if using a socket as a timer would also prevent JIT compilation?
luasocket uses the classic Lua C API for its functions, which will prevent JIT compilation in the same manner as LÖVE's functions do.
time thief wrote:Thinkng about it more, does that really matter? The JIT doesn't really need to compile the loop, just the function being tested (called from within the loop). I don't care about the performance of the loop, just the function being tested.
LuaJIT doesn't specifically compile individual functions, it looks at what is actually being executed at runtime (without being restricted to specific blocks of scope like functions) and determines what to compile from there. Functions may be inlined (or not, depending), among a large amount of other potential optimizations.
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests