Thread Tools Display Modes
11-07-15, 05:31 PM   #1
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 123
OnUpdate running function and memory saving

Disabling all add-ons and leaving active only the one created by me, I noticed large swings in memory consumption. This is probably because in OnUpdate event is launched this function, where tables are created all the time:

Lua Code:
  1. local function tokenize(C, strng)
  2.     local sChar = string.format('%c', C)
  3.     local sInput = strng or ""
  4.     local tReturn = {}
  5.     for sWord in string.gmatch(sInput, "[^"..sChar.."]+") do
  6.         table.insert(tReturn, tonumber(sWord) or sWord)
  7.     end
  8.     return tReturn
  9. end
  10.  
  11. local function gettok(sInput, iPosition, Separator, iRange)
  12.     local tTokens = tokenize( Separator, sInput )
  13.     if iPosition == 0 then return sInput end
  14.     local iStart, iStop = (iPosition > 0) and iPosition or (#tTokens + iPosition + 1)
  15.     if not iRange or iPosition == iRange then
  16.         return tTokens[iStart]
  17.     end
  18.     if iRange > 0 then
  19.         iStop = iRange
  20.     elseif iRange == 0 or (iStart + iRange) > #tTokens then
  21.         iStop = #tTokens
  22.     else
  23.         iStop = iStart + iRange + 1
  24.     end
  25.     if iStart == iStop then return tTokens[iStart] end
  26.     if iStart > iStop then
  27.         iStart, iStop = iStop, iStart
  28.     end
  29.     return table.concat(tTokens, Separator, iStart, iStop)
  30. end

Where

• sInput = string to manipulate
• iPosition = position of the token inside the string. If lesser than 0, it will be considered the position from the last token to the first. If equal to 0, returns the whole string.
• Separator = ASCII code of the token separator
• iRange = optional: if specified, returns the token from position to range. If equal to 0, return all tokens from position to the end of the string.

Some examples:

local text = "apple.banana.cherry.grape.orange"

gettok(text,1,46)
> apple

gettok(text,-2,46)
> grape

gettok(text,2,46,4)
> banana.cherry.grape

gettok(text,-1,46,-3)
> cherry.grape.orange

Now, can you give me some advice on how to eliminate these fluctuations in memory usage by bringing, as much as possible, some small example, and improve this code?

Thank you in advance
  Reply With Quote
11-07-15, 05:47 PM   #2
sylvanaar
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Sep 2006
Posts: 92
Besides the obvious of not doing too much work in OnUpdate, why don't you reuse the table, since the function is called so much, you will reduce the GC overhead

just place

Lua Code:
  1. local tReturn = {}

Right outside of tokenize instead of where it is, then in place of it

Lua Code:
  1. wipe(tReturn)
  Reply With Quote
11-07-15, 06:20 PM   #3
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 123
The best solution of all would resort to the use of metatables. In a Lua language mailing list was suggested this: a table created once and for all for each string

Lua Code:
  1. local tok_meta = { __index = { gettok =
  2.    function(tbl,i,j)
  3.      local n=#tbl
  4.      j = j or i
  5.      if i and i<0 then i=n+i+1 end
  6.      if j and j<0 then j=n+j+1 end
  7.    return table.concat(tbl,tbl.sep,i,j) end }}
  8.  
  9. local tokens = function(str,sep)
  10.    local fields={sep=sep}
  11.    str:gsub(("[^%s]+"):format(sep),function(field)
  12.       fields[#fields+1]=field
  13.       end)
  14.    return setmetatable(fields,tok_meta)
  15. end
  16.  
  17. local s = tokens( "apple.banana.cherry.grape.orange",".")
  18.  
  19. > s:gettok(1)
  20. apple
  21. > s:gettok(-2)
  22. grape
  23. > s:gettok(2,4)
  24. banana.cherry.grape
  25. > s:gettok(-3,-1)
  26. cherry.grape.orange

The ideal for me would switch functions gettok and tokens, by inserting tokens inside the tok_meta metatable and gettok as a function of its own, because in addition to it there are other string manipulation functions. But I'm still very little practical with metatable and not would know what can I do, so expect your lights

Last edited by Benalish : 11-07-15 at 06:29 PM.
  Reply With Quote
11-07-15, 07:59 PM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Can you explain what you're actually trying to accomplish with this code? Not just "split apple.banana.cherry.grape.orange into cherry.grape" but the general end goal. Metatables are almost certainly a wild overcomplication, but without a higher-level context it's pretty hard to offer any useful suggestions.

(Also, your second post is not only creating a new table, but also a new function, every time you call "tokens" -- those are both things you should avoid at pretty much all costs in an OnUpdate script.)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » OnUpdate running function and memory saving


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