Casualist
|
  |
| Joined: 26 Jun 2014 |
| Total Posts: 4443 |
|
|
| 23 Jul 2014 05:57 PM |
I ask because I am doing some pseudo hot-swapping in some classes for performance reasons and wanted to know if what I am doing is counter intuitive memory wise.
Some pseudo code for reference:
return function(args) local this = {} -- upvalue
function updateMethods() if conditions then function this:method1() --blah end elseif foo then function this:method1() --bar end else function this:method1() --another optimized function end end
updateMethods() function this:updateSomeValue(val) this[index] = val updateMethods() end
return setmetatable({}, some_metatable) end |
|
|
| Report Abuse |
|
|
Oysi
|
  |
| Joined: 06 Jul 2009 |
| Total Posts: 9058 |
|
|
| 23 Jul 2014 06:17 PM |
That could in absolutely no way increase your performance. What you're doing makes no sense. |
|
|
| Report Abuse |
|
|
Casualist
|
  |
| Joined: 26 Jun 2014 |
| Total Posts: 4443 |
|
|
| 23 Jul 2014 06:38 PM |
@Oysi
It increases performance for calculation heavy functions by optimizing the equations/variables used.
Instead of having to check a bunch of internal conditions with every call like this
function blah() if not slack then if not shearDist then -- math else -- math end elseif not shearDist then -- math else -- math end end
The index would instead point to an optimized function base on those pre-existing conditions. When you are making something like 30000 calls/second on a function that indexes a few functions like this the marginal performance gains from not having to check conditions and the optimized math adds up.
But my practices whether or not they make sense aren't the issue, I'm asking if the function value that used to be indexed by this:method1 would be garbage collected if I replaced said function with a different one. |
|
|
| Report Abuse |
|
|
Oysi
|
  |
| Joined: 06 Jul 2009 |
| Total Posts: 9058 |
|
|
| 23 Jul 2014 07:10 PM |
Oh, so that's what you're doing. Well, if you're using objects and calling functions from them, that adds more overhead than those checks would, anyway. Meaning that there is most likely other parts of your thing that you can optimize more.
Anyway, yes, this would spit out a whole ton of garbage, because you're creating the functions over and over again. What you want to do is just create the functions before-hand, and then set the value for the actual function thingy to any of those pre-created functions. This way you won't be creating a ton of functions, and you can still use the same function for multiple objects with the 'self' parameter.
There are multiple ways of going about this, but generally you just want something simple like:
local function f1(self) print("potato") end local function f2(self) print("cake") end
...balblalba.
function updateMethods() if wantGoodFood then f = f1 else f = f2 end end
If you're setting the function to an object like:
this.f = f1
Then you can trigger the 'self' parameter by doing:
this:f() -- calls the function with 'this' as the self parameter this:f(1, 2, 3) -- same thing, but adds in more arguments
Btw, when doing stuff like this, remember to still split your thing into more functions. You don't want a huge list of 100 functions where each one does the whole process in a very special way. What you want is maybe a list with 2 or more functions for each individual process. |
|
|
| Report Abuse |
|
|
Casualist
|
  |
| Joined: 26 Jun 2014 |
| Total Posts: 4443 |
|
|
| 23 Jul 2014 08:01 PM |
I thought of that, so instead of looping through a table of constraint objects to call :solve() on I'm now pre-indexing them and adding them to the table I loop through. Then whenever updateMethods() is called I'll update the appropriate index in my main table to my object's new :solve() method. It's a tad memory heavy, but the performance is decent.
:/ Figured that would be the case, I knew roblox gc'd tables and userdata but wasn't sure about functions. Thank you for clarifying.
What I'll probably do is create the functions as needed like so:
local f1, f2, f3, f4...
function updateMethods() if firstcondition then this.method = f1 or function() --do stuff end elseif second condition then this.method = f2 or function() --other stuff end elseif ..... end
To avoid consuming a lot of memory unless required.
|
|
|
| Report Abuse |
|
|