Do I need to think about how much debug spew I print out?

Thanks everyone for the detailed information. Perhaps I am overthinking this (in my day job I’m a project manager for a product that manages a log with different levels of detail for different debug levels - but it’s native kernel level events for retail skus so perf impact is negligible).

In Lua is there anything like a precompiler command I might use to let me leave in debug spew for debugging, but omit them from ship builds? I looked through Corona SDK build file documentation and was surprised that there’s nothing like this.

I don’t think Lua has any precompiler commands, certainly I’ve never seen anything about them.  

As I mentioned before, I use an Ant script to comment out all of my print commands, and then reverse that when I go back to debugging (projectDir is the location of your Corona project):

\<!-- COMMENT ALL INSTANCES OF PRINT --\> \<replaceregexp byline="true" match="print\((.\*)" replace="--RELEASEPRNT\(\1"\> \<fileset dir="${projectDir}"\> \<include name="\*.lua"/\> \</fileset\> \</replaceregexp\> \<!-- UNCOMMENT ALL INSTANCES OF PRINT --\> \<replaceregexp byline="true" match="--RELEASEPRNT\((.\*)" replace="print\(\1"\> \<fileset dir="${projectDir}"\> \<include name="\*.lua"/\> \</fileset\> \</replaceregexp\>

One thing to mention is that this will break your code if you have any inline print statements. For example this:

if something then print("something happened") end

would become this:

if something then --RELEASEPRNT("something happened") end

and so the “end” would be commented out and the if statement would be broken.

To fix this just change any inline print calls so they are on multiple lines:

--now this if something then print("something happened") end --becomes this if something then --RELEASEPRNT("something happened") end

@thomas6 - to a certain degree I would agree with you, for instance when you just print things like “aaa”, “bbb” etc to try and find exactly where some code is breaking then yes I would remove those after the problem is fixed.

But for a larger project, having print statements in the project is still useful throughout debugging. It’s very easy to change one part of the project and accidentally have it affect another part, so having a healthy amount of data printing out is extremely useful. I’m not saying that my method is perfect, but it lets me have as much output as I like during debugging, and zero print calls being made on release builds, which seems pretty good to me.

@ Alan: You’re right, that is definitely a very good and practical way of working.

More flavor for the conversation.

Time cost for following:

  • 1 - Empty defunct print x 1,000,000 iterations
  • 2 - Concatenation + math.random() call in defunct print x 1,000,000 iterations
  • 3 - Same as 2 + ‘debug’ shortcut flag  – Flag set to true
  • 4 - Same as 3 – Flag set to false (i.e. don’t do catenation or math.random() call)

Results on my machine:

Test 1 43 ms -- Baseline Test 2 1121 ms -- Expensive, even if defunct. Test 3 1103 ms -- About the same w/ test Test 4 74 ms -- Big savings!

The code:

local getTimer = system.getTimer local \_print = print print = function() end local iterations = 1000000 -- Test 1 local began = getTimer() for i = 1, iterations do print() end local ended = getTimer() \_print("Test 1 " .. ended - began .. " ms") -- Test 2 local began = getTimer() for i = 1, iterations do print( "Corona" .. " is " .. "Cool: " .. tostring(math.random(1, iterations) ) ) end local ended = getTimer() \_print("Test 2 " .. ended - began .. " ms") -- Test 3 - Debug control flag (ON) \_G.myDebugEn = true local began = getTimer() for i = 1, iterations do print( myDebugEn and ("Corona" .. " is " .. "Cool: " .. tostring(math.random(1, iterations) ) or "" ) ) end local ended = getTimer() \_print("Test 3 " .. ended - began .. " ms") -- Test 4 - Debug control flag (OFF) \_G.myDebugEn = false local began = getTimer() for i = 1, iterations do print( myDebugEn and ("Corona" .. " is " .. "Cool: " .. tostring(math.random(1, iterations) ) or "" ) ) end local ended = getTimer() \_print("Test 4 " .. ended - began .. " ms")

You guys are awesome!!

Thank you for the input and the data, this is really powerful. I’m not familiar with Ant scripts, but I understand what you’re doing, this is really smart.

I heard a rumor that a coworker used to be a dev lead at LucasArts and is allegedly is a Lua guru, so surely he’s come across something like this… I’m going to try to chase him down today or tomorrow, I’ll report back as soon as I learn more.

I suspect I’ll take Alan’s approach and use some sort of script to toggle my builds in/out of debug mode.

how the suggested “isRelease” flag could be implemented in a cross-platform manner ?

Well the simplest way would be to add this to the top of your main.lua file:

isRelease = false

and then set it to:

isRelease = true&nbsp;

when building your release mode builds.

I spoke to my coworker (who was a dev lead on several AAA titles that used lua). They solved this problem unfortunately through making changes to the Lua compiler to basically implement precompiler commands of their own. I doubt this is feasible for us in Corona.

His suggestion was to use Alan’s first suggestion where you just override the definition of print().

Well, you could probably do something in Enterprise, but for Pro … probably no so much.