Is your game running slow?
Have you ever wished you could profile rabidly obnoxious bottlenecks effortlessly?
Well then PROBE.lua is for you!
I hope you'll find it useful! If not, it was fun to write.
I'm open to comments/suggestions/feature requests/bug reports/you name it!
Source: https://github.com/jorio/PROBE
Demo: see attachments
Screenshot of the demo below. The actual profiler is the two bars on the sides; the colored junk in the middle is what's being profiled.
Latest update 2014-08-22
2014-08-22: pause/resume on the fly (PROBE.enable()), preserve return values of hooked functions (thanks for the heads-up lemtzas)
2014-08-03: first version
PROBE.lua: realtime graphical profiler
PROBE.lua: realtime graphical profiler
- Attachments
-
- probedemo2.love
- updated 2014-08-22
- (5.67 KiB) Downloaded 235 times
Last edited by Chèvre on Fri Aug 22, 2014 2:00 pm, edited 1 time in total.
Re: PROBE.lua: realtime graphical profiler
this is amazing!
i suggest you do whatever you can to make this auto-detect the settings: "GPROFILER:hookAll(_G, "draw", {love, lg})" i don't really know what this means, but do i need to know? what if "GPROFILE:hookAll("draw")" did the rest by default?
also it'd be nice if you could make it auto-detect the screen size and you could just do something like: probe.draw(CPROFILE, GPROFILE, ...) and it would draw the columns without you specifying coordinates
these are all usability suggestions, the library itself is very impressive and i'm using it immediately
i suggest you do whatever you can to make this auto-detect the settings: "GPROFILER:hookAll(_G, "draw", {love, lg})" i don't really know what this means, but do i need to know? what if "GPROFILE:hookAll("draw")" did the rest by default?
also it'd be nice if you could make it auto-detect the screen size and you could just do something like: probe.draw(CPROFILE, GPROFILE, ...) and it would draw the columns without you specifying coordinates
these are all usability suggestions, the library itself is very impressive and i'm using it immediately
Re: PROBE.lua: realtime graphical profiler
Hi! Thanks for the feedback! You're right, placing hooks automatically isn't the most intuitive thing in the world. I should write a tutorial and/or provide a sensible mass-hook default function.
But the gist of it is:
Now for B., assuming Missile/Enemy/Player are global tables, you can do this instead:
This will look in all subtables of _G (in Lua, _G is the table of all globals) for functions named 'draw' and place a profiling hook on it. In other words, it'll match:
_G.Enemy.draw
_G.Missile.draw
_G.Player.draw
_G.love.draw
Oops! We don't want to place an automatic hook on love.draw(). That's why we give hookAll a list of tables to skip, in this case just {love}.
(Technical reason why you don't want to place a hook on love.draw(): hooks actually just wrap a function call in an event; events may only occur in a "profiling cycle"; but you start and end the cycles in love.draw(), so if an event is triggered before a cycle exists, the profiler will crash)
Similarly, in the little example posted on github, I've also told the profiler to ignore lg. I used "lg" as an alias for "love.graphics". Since I don't want the profiler to place a hook on love.graphics.draw (through lg.draw), I told it to ignore lg.
Note that while it is dangerous to profile love.draw, it's totally okay to profile love.graphics.draw (that's the one that draws images). You can even profile LÖVE itself, e.g. love.graphics.rectangle, love.graphics.print, etc.
So I've mainly talked about hooks on functions here, but you can also create little events in your code with pushEvent()/popEvent() (it's really simple). I recommend reading main.lua from the demo because it explores all possible use cases. Also, don't hesitate to read the comments in PROBE.lua, they also describe how you should call each function.
While writing this post, I've realized the API could be made more intuitive, and I'll think of ways to simplify interaction with the hook mechanism. I should also post tutorials/luadocs somewhere Thankfully, you only need place hooks once (typically in love.load()) and then you don't have to touch them again, so if you'd like to use the profiler right away, you don't really *need* to understand the hook conundrum in-depth. But I'm really glad it's useful to you!
But the gist of it is:
- create a new profiler
- surround code that you would like to profile with profiler:startCycle() and profiler:endCycle() (typically in love.draw() or love.update())
- create "events" for which you'd like to have detailed statistics
- hook each individual function by hand
- mass-hook a ton of functions that have the same name
Code: Select all
profiler:hook(Missile, 'draw', 'draw a missile')
profiler:hook(Enemy, 'draw', 'draw an enemy')
profiler:hook(Player, 'draw', 'draw myself')
Code: Select all
profiler:hookAll(_G, 'draw', {love})
_G.Enemy.draw
_G.Missile.draw
_G.Player.draw
_G.love.draw
Oops! We don't want to place an automatic hook on love.draw(). That's why we give hookAll a list of tables to skip, in this case just {love}.
(Technical reason why you don't want to place a hook on love.draw(): hooks actually just wrap a function call in an event; events may only occur in a "profiling cycle"; but you start and end the cycles in love.draw(), so if an event is triggered before a cycle exists, the profiler will crash)
Similarly, in the little example posted on github, I've also told the profiler to ignore lg. I used "lg" as an alias for "love.graphics". Since I don't want the profiler to place a hook on love.graphics.draw (through lg.draw), I told it to ignore lg.
Note that while it is dangerous to profile love.draw, it's totally okay to profile love.graphics.draw (that's the one that draws images). You can even profile LÖVE itself, e.g. love.graphics.rectangle, love.graphics.print, etc.
So I've mainly talked about hooks on functions here, but you can also create little events in your code with pushEvent()/popEvent() (it's really simple). I recommend reading main.lua from the demo because it explores all possible use cases. Also, don't hesitate to read the comments in PROBE.lua, they also describe how you should call each function.
While writing this post, I've realized the API could be made more intuitive, and I'll think of ways to simplify interaction with the hook mechanism. I should also post tutorials/luadocs somewhere Thankfully, you only need place hooks once (typically in love.load()) and then you don't have to touch them again, so if you'd like to use the profiler right away, you don't really *need* to understand the hook conundrum in-depth. But I'm really glad it's useful to you!
Re: PROBE.lua: realtime graphical profiler
thanks for explaining that, it really helps. i didn't have a lot of my classes imported into main.lua, which meant it didn't automatically profile everything with the example line - so i was confused by that. this is really great
Re: PROBE.lua: realtime graphical profiler
Thanks! I found this really useful for tracking down bottlenecks in my game.
I had to make a modification though (functions that return values wouldn't profile correctly, so I packed, stored, unpacked, and returned the results).
A couple other features I'd like (or will probably make on my own eventually) are clearing all tracked functions and/or telling it to not worry about running a function without starting a cycle and/or the ability to toggle tracking. So I can quickly add/remove it without it getting too uppity when functions get called outside the segment i'm actually tracking.
I had to make a modification though (functions that return values wouldn't profile correctly, so I packed, stored, unpacked, and returned the results).
A couple other features I'd like (or will probably make on my own eventually) are clearing all tracked functions and/or telling it to not worry about running a function without starting a cycle and/or the ability to toggle tracking. So I can quickly add/remove it without it getting too uppity when functions get called outside the segment i'm actually tracking.
Re: PROBE.lua: realtime graphical profiler
Hi! Great! Thank you for giving it a try!lemtzas wrote:Thanks! I found this really useful for tracking down bottlenecks in my game.
Sorry about the delay. Reply notifications were turned off
Whoops! Nice find. I should've thought about this. I've updated it.lemtzas wrote:I had to make a modification though (functions that return values wouldn't profile correctly, so I packed, stored, unpacked, and returned the results).
You can try unhook().lemtzas wrote:A couple other features I'd like (or will probably make on my own eventually) are clearing all tracked functions and/or telling it to not worry about running a function without starting a cycle and/or the ability to toggle tracking. So I can quickly add/remove it without it getting too uppity when functions get called outside the segment i'm actually tracking.
I've also added an "enable()" function that lets you pause/resume profiling at any time. Check out the updated demo in the thread's top message.
Btw, don't hesitate to send pull requests for any changes you make
Who is online
Users browsing this forum: No registered users and 2 guests