Sign in to follow this  
IIYAMA

What is faster?

Recommended Posts

What is a faster way to use? (I need to check a lot all the players.)

  
getElementsByType("player") 
  
--or 
  
-- a table that already contains all players? 
local myPlayers = {} 
  
  
  
  
for I, player in ipairs () do 
  
end 
  

Share this post


Link to post

I think the first would be the fastest. If you do it the second way, you have to keep updating the table.

Also, if you want to check lots of players, I would recommend just getting a list of players eligible for the thing you want (if applicable).

Share this post


Link to post

Well updating the table isn't the problem, I am talking about looping through a table that is active every 0.3 seconds. (only when the timer should be active)

When I use getElementsByType("player") it will update the whole table again and after executing the data will be gone.

But when I update this table with onPlayerJoin and onPlayerQuit. I don't have to reload the whole table, but it will remain in to the memory.

Share this post


Link to post

Sample:

local myPlayers = {} 
  
addEventHandler ( "onPlayerQuit", getRootElement(),  
function () 
  for i, player in ipairs(myPlayers) do 
    if player == source then 
      table.remove (myPlayers,i) 
      return 
    end 
  end 
end) 
  
addEventHandler ( "onPlayerJoin", getRootElement(),  
function () 
  table.insert (myPlayers,source) 
end) 
  
setTimer (function () 
for i, player in ipairs(myPlayers) do 
  
end,300,1) 
  
 -- or ------------------------------------------- 
  
setTimer (function () 
  for i, player in ipairs(getElementsByType ("player")) do 
  end 
end,300,1) 
  

Edited by Guest

Share this post


Link to post

ok

thank you,

Share this post


Link to post

Updating the table is faster than using getElementsByType every time. When you call getElementsByType, you are creating a new table and doing this every 0.3 seconds isn't efficient. When you update the table, the slowest code to execute is looping through all players and using table.remove (which also pushes all elements back by one index) and doing this when the player leaves isn't that much. So if you're after performance, update the table instead of creating a new one. By the way, it's better to use the player element as the key for the table:

--onPlayerJoin 
myPlayers[source] = true 
  
--onPlayerQuit 
myPlayers[source] = nil 
  
--looping through all players: 
for player in pairs(myPlayers) do 
  
end 

No need to loop through the table on quit, Lua will take care of what's needed, resulting in best performance.

Share this post


Link to post

Can you loop key's O_o?

Share this post


Link to post
Can you loop key's O_o?

What do you mean?

There are 2 functions for iteration.

pairs and ipairs

http://www.lua.org/pil/7.3.html

Also, I've mentioned that in someone's topic that getElementsByType is not recommended for very frequent use for server. You can use client's power for this since most servers don't have as much processing power as client's PC. For you it will be more efficient to use a global table and update it when needed.

Share this post


Link to post
pairs and ipairs 

This was very unclear for me, I saw differed topic's about it, but they all gave differed answers and nobody seems to know the exact differences. Very confusing...

Ok, I will put them in a table

thank you all

Share this post


Link to post

ipairs can only iterate indexed tables that have the indexes in order (1,2,3,4,5,6,7,8,9 and so on) while pairs can iterate any kind of table. Instead of using these functions, you can use next, which will work for both indexed and non-indexed tables. Here's an example of its usage:

local table = { ["wheels"] = true, ["doors"] = true } 
local table2 = { [1] = "Hi, I'm ixjf!", [2] = "Bye!" } 
  
for k,v in next, table do 
    print ( k, v ); 
    --[[OUTPUT: 
        wheels  true 
        doors  true]] 
end 
  
for i,v in next, table2 do 
    print ( i, v ); 
    --[[OUTPUT: 
        1  Hi, I'm ixjf! 
        2  Bye!99]] 
end 

Edited by Guest

Share this post


Link to post

ok

yes, now I understand it.

:)

oh one question:

when I put a table index or table key to nil, will it be totally gone?

or will the key remain?

Share this post


Link to post

The field will still exist, but you will not be able to assign a value to it (unless you meant set the value of the field to false/nil)/get the value from it.

By the way, read my reply above, I added something.

Share this post


Link to post

hmm interesting

If I set a player to true. Let we say I got everyday 100 players in my server, will this table get any bigger? and will it gives more lagg at while using this for a long time before I reset the table: myTable ={}

  
myTable ={} 
myTable[player] = {} 
  
myTable[player] = nil 
  

Share this post


Link to post

The table will continuously get bigger, since you only set fields' value to nil, you don't actually remove them (you can however use table.remove to do that). I can't tell much about lag, but I'd say yes it would (principally when iterating, it will loop through all fields), though I don't think that would affect much the gameplay, if at all.

Share this post


Link to post
The table will continuously get bigger, since you only set fields' value to nil, you don't actually remove them (you can however use table.remove to do that). I can't tell much about lag, but I'd say yes it would (principally when iterating, it will loop through all fields), though I don't think that would affect much the gameplay, if at all.

That's wrong, when speaking about performance. Calling the function is definitely slower and setting it to nil will suffice in most cases, even if the table isn't rehashed in lua.

Share this post


Link to post

When you set the value of the field to nil, that field is removed, so the memory will be freed. That's the point of nil - it is a way to represent the absence of the value. That's the reason why you get nil from non-existing variables or uninitialized fields of the table. If nil didn't have such special behavior, it would be not different from false, therefore an useless duplicate.

Share this post


Link to post
When you set the value of the field to nil, that field is removed, so the memory will be freed. That's the point of nil - it is a way to represent the absence of the value. That's the reason why you get nil from non-existing variables or uninitialized fields of the table. If nil didn't have such special behavior, it would be not different from false, therefore an useless duplicate.

Yes, it's true for most languages, but not for Lua. Setting a single value as nil doesn't force a rehash, so the table size remains the same (initially). Though as I mentioned, that is not a problem in most cases anyways.

Share this post


Link to post

Well guys,

http://lua-users.org/wiki/StoringNilsInTables

Storing Nils In Tables

Lua tables make no distinction between a table value being nil and the corresponding key not existing in the table. t = {[k] = nil} is identical to t = {} , and t[k] evaluates to nil when k is not a table key. In fact, you may think of {} as a table with all possible keys set to nil, and this still takes only a small finite amount of memory because all those keys having nil values are not explicitly stored. Furthermore, attempting to set a table key as nil, e.g. {[nil] = true} , raises a run-time error. This is unlike various other common languages. [1]

I do it my way. :D

local lossObjectT = 0 
function objectTimer () 
    for k, objectTable in pairs (objectExpl) do 
        local Timer = objectTable[2] 
        if Timer then 
            Timer = Timer - 1 
            if Timer > 0 then 
                objectExpl[k][2] = Timer 
            else 
                objectExpl[k][2] = nil 
                local object = objectTable[1] 
                if isElement(object) then 
                    activateObject(object,objectTable[3])        
                end 
            end 
        end 
    end 
    lossObjectT = lossObjectT +1 
    if lossObjectT > 5 then 
        lossObjectT = 0 
        for i, objectTable in pairs (objectExpl) do 
            while objectExpl[ i ] and not objectExpl[ i ][2] do 
                table.remove(objectExpl,i) 
            end 
        end 
    end 
    if #objectExpl <= 0 and isTimer(objectExplTimer) then 
        killTimer(objectExplTimer) 
    end 
end 

I may can set the table like this: objectExpl = {}

when I stop the timer, but I am not sure if that is better then remove with table.remove.

I have seriously no idea how you guy would script this.

Share this post


Link to post
When you set the value of the field to nil, that field is removed, so the memory will be freed. That's the point of nil - it is a way to represent the absence of the value. That's the reason why you get nil from non-existing variables or uninitialized fields of the table. If nil didn't have such special behavior, it would be not different from false, therefore an useless duplicate.

Yes, it's true for most languages, but not for Lua. Setting a single value as nil doesn't force a rehash, so the table size remains the same (initially). Though as I mentioned, that is not a problem in most cases anyways.

Garbage collector will deal with it. Setting value of nil will "remove" the field from a table as well as memory. This is also what you have to do when clearing shader/texture from memory. Simple destroyElement will only destroy the MTA element from memory but the memory address (a value) in a variable is still there, therefore it is necessary to nil the variable in order to free the RAM.

Simple example explaining nil'ing variables:

local tab = { 1,2,3,4,5,6 }; -- simple indexed table of size: 6 
  
function table.size( t ) 
    local i = 0; 
    for k,v in pairs( t ) -- I use pairs in case "t" will be non-indexed table or one of table fields will be nil 
        i = i + 1; 
    end 
    return i; 
end 
  
print( table.size( tab ) ); -- this will show you 6 
tab[ 2 ] = false; -- assign new value of false to index 2 
print( table.size( tab ) ); -- it's still 6 
tab[ 2 ] = nil; -- delete the field at index 2 
print( table.size( tab ) ); -- now you will see 5 because tab[2] does not hold any value and therefore size of the table will change 
  

Share this post


Link to post

ok, it is now clear for me.

What is the Garbage collector?

Edited by Guest

Share this post


Link to post

Its main role is to free the RAM from unused data (nil a variable and memory will be freed by garbage collector). Basically, something you don't need to worry about.

Share this post


Link to post

Just a question:

You have at least 1 GB RAM, at least 2 GHz of CPU...

What does it matter if the table is 1 KB bigger?

About pairs and ipairs:

in a benchmark, pairs is faster than ipairs, but ipairs is sorted for sure.

Also, have you ever benchmarked "getElementsByType" and the table yourself? Just let it run 200 times and check how long it takes. I'd still use "getElementsByType" since it is easier to manage and less prone to bugs. Also don't forget that calling a code each 300 ms is kind of useless. It just means that the LUA engine has more stuff to do, even though it doesn't need to do it.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.