Thread Tools Display Modes
08-19-09, 05:25 PM   #1
modus
A Deviate Faerie Dragon
 
modus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 14
Too much garbage!

Hey there! I'm working on an add-on currently with a garbage generation problem. It checks combat log events and when you enter combat, its memory taken just gets higher and higher until your FPS is decimated or you do a manual garbage collection. I've read up on how and why this happens (grew up on Java) and have implemented several fixes, but I'm left with one problem.

One of the things my add-on can do is logical operation checks on some combat log event parameters. For example, for a unit's flags, you might specify "MINE and PLAYER and FRIENDLY", and the add-on would then check that flag to match all of those things before determining whether or not it is a match. My current method involves first parsing out all parameters, checking whether or not they match, and then replacing them with a string "true" or "false" (using a gsub). At the end, the resulting string is placed with loadstring("return "..thatString) to get the return value.

Anyway, this is evidently creating a new function which is adding to my garbage. I determined this by commenting out just that line and changing it to "return true", which obviously produced erroneous results, but added no garbage. So my questions are:
  1. Is there a way of doing this that creates no garbage?
  2. Is there a better way to evaluate a logical expression than a loadstring? I suppose I could write my own function, but it'd be difficult to make one more perfect than Lua's own.
__________________

Last edited by modus : 08-19-09 at 05:27 PM. Reason: Clarification on methodology.
  Reply With Quote
08-19-09, 06:55 PM   #2
yssaril
A Warpwood Thunder Caller
 
yssaril's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2007
Posts: 96
would you mind showing us a codesample (its alot easier to figure out that what you wrote :P)
  Reply With Quote
08-19-09, 07:06 PM   #3
modus
A Deviate Faerie Dragon
 
modus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 14
Originally Posted by yssaril View Post
would you mind showing us a codesample (its alot easier to figure out that what you wrote :P)
Well sure! It'll take a little context but it's not bad.

Code:
function EX_CheckExtraFilter(extraFilterString)
	
	if extraFilterString == "" or extraFilterString == nil then return true end
	
	local argumentPattern = "[^&|()!][^&|()]*"
	extraFilterString = gsub(extraFilterString, argumentPattern, EX_ExtraFilterGsub)
	
	return EX_Evaluator(extraFilterString)
end

function EX_ExtraFilterGsub(eachArgument)
	return tostring(EX_ExtraFilterHandler(eachArgument))
end
This function is called on each "extra filter". An extra filter is something that is not event based but relevant, like whether or not the player is in combat or in an arena. I define how those filters are handled, but a good example would be:
  • inbattleground|inarena
The above functions would, if the player is in an arena, pass "false|true" to the EX_Evaluator function, which is here below:

Code:
function EX_Evaluator(argString)

	argString = gsub(argString, "&", " and ")
	argString = gsub(argString, "!", "not ")
	argString = gsub(argString, "%||", " or ")
	
	return loadstring("return "..argString)

end
It just converts the logical operators to what Lua expects and then returns the result. This function would receive the "false|true", convert it to "false or true" then loadstring("return false or true"), which would be true. This step is creating a function, though, which seems to be adding to my garbage.
__________________

Last edited by modus : 08-19-09 at 07:09 PM.
  Reply With Quote
08-19-09, 07:14 PM   #4
yssaril
A Warpwood Thunder Caller
 
yssaril's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2007
Posts: 96
do these filters ever change once set?
  Reply With Quote
08-19-09, 07:16 PM   #5
modus
A Deviate Faerie Dragon
 
modus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 14
Originally Posted by yssaril View Post
do these filters ever change once set?
Possibly with new versions but not on the fly.
__________________
  Reply With Quote
08-19-09, 07:25 PM   #6
yssaril
A Warpwood Thunder Caller
 
yssaril's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2007
Posts: 96
then simply cache your loadstring

try something like this where you make the loaded string into an actual function and save that function then reuse it if needed

Code:
local cache = {}
function EX_CheckExtraFilter(extraFilterString)
	if cache[extraFilterString] then return cache[extraFilterString]() end
	local cacheString = extraFilterString
	if extraFilterString == "" or extraFilterString == nil then return true end
	
	local argumentPattern = "[^&|()!][^&|()]*"
	extraFilterString = gsub(extraFilterString, argumentPattern, EX_ExtraFilterGsub)
	cache[cacheString] = EX_Evaluator(extraFilterString)
	return cache[cacheString]()
end


function EX_Evaluator(argString)

	argString = gsub(argString, "&", " and ")
	argString = gsub(argString, "!", "not ")
	argString = gsub(argString, "%||", " or ")
	
	return loadstring("return function() return "..argString.."end")
end
total drycode no clue if it works
  Reply With Quote
08-19-09, 07:29 PM   #7
modus
A Deviate Faerie Dragon
 
modus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 14
Well, the extra filters themselves wouldn't be changing, but the expressions would. The loadstring will be loading a different string almost each time.
__________________
  Reply With Quote
08-19-09, 07:34 PM   #8
yssaril
A Warpwood Thunder Caller
 
yssaril's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2007
Posts: 96
then you need to look at someway else to do it cause loadstring is something you want to avoid at all cost its expensive and creates garbage etc

you may have to write a parser that looks through your strings and then executes them

like if it finds "something1 operator1 something2" it finds and extracts all 3 parts and then because if finds operator1 it does that operation to something1 and something2
  Reply With Quote
08-19-09, 07:39 PM   #9
modus
A Deviate Faerie Dragon
 
modus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 14
Originally Posted by yssaril View Post
then you need to look at someway else to do it cause loadstring is something you want to avoid at all cost its expensive and creates garbage etc

you may have to write a parser that looks through your strings and then executes them

like if it finds "something1 operator1 something2" it finds and extracts all 3 parts and then because if finds operator1 it does that operation to something1 and something2
Fair enough. This seems like a fairly standard operation, though. Is there a common library for parsing out logical expressions? Something like a gsub, except with logic?
__________________

Last edited by modus : 08-19-09 at 07:42 PM.
  Reply With Quote
08-19-09, 07:48 PM   #10
yssaril
A Warpwood Thunder Caller
 
yssaril's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2007
Posts: 96
nope any parser is usually custombuilt because generic parsers tend to be very inefficient. also instead of doing alot of string operations why not simply work with the data you have get all the individual args out of it and then go from there something just seams wrong with having to parse so many strings

yes while loadstring is a standard function it is a very expensive one because you are basically compiling code on runtime so alot of things have to be done to get that done
  Reply With Quote
08-19-09, 07:53 PM   #11
modus
A Deviate Faerie Dragon
 
modus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 14
Alright then. Since Java is my native language, loadstrings felt dirty anyway. I'll write my own parser.
__________________
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Too much garbage!


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off