Jump to content

[QUESTION] Different types of 'for' loops.


koragg

Recommended Posts

Hello, @LosFaul recently told me that using this:

local player = getElementsByType("player")
for i = 1, #player do ... end

is better than using this:

for i, player in ipairs(getElementsByType("player")) do ... end

Are there any huge benefits to using the first over the second method? Most of my scripts are made with the second one but if benefits are big I'd edit them to use the more efficient one. Thoughts?

Edited by koragg
Link to comment
  • Moderators

The second one is using the ipairs function: https://www.lua.org/pil/7.3.html

 

Benefit of the ipairs:

  • ipairs returns the value as wel as the index. (no need to index on the next line as with the normal for loop)
  • ipairs stops if there is no item at a given index: (not always a benefit thought)
    table = {
    	1, 
    	nil, -- < stops here
    	3
    }

     

 

Benefits of the normal for loop:

  • Faster because it isn't using a function to loop. (functions are relative slow in compare to the rest of the code.)
  • Can loop through nil values if required.
    table = {
    	1, 
    	nil, -- < keeps going!
    	3
    }

     

  • Can loop with different steps:
    for i=2, 10, 2 do
    --[[
    2
    4
    6
    8
    10  
    ]]
    end

     

  • Can loop invert:
    for i=10, 1, -1 do
    --[[
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    ]]
    end

     

 

With other words there is no reason to use ipairs in my opinion.

 

  • Like 1
  • Thanks 1
Link to comment

There's also this pretty useful page: https://springrts.com/wiki/Lua_Performance
Where you can see in test 9, that using for i-1, #table is more than 2 times faster than using ipairs. In reality you shouldn't bother with such micro optimizations if you aren't traversing tables with thousands of elements pretty often. The page can be pretty useful if you want to read more about lua optimization quirks tho.

  • Thanks 1
Link to comment
  • Moderators

local's are faster, because they are only active inside of an area.

Real world example: It is something similar as buying things online in your own country(can be done within 24-hour) or order them from another(takes more than a day).

Note: default MTA default functions are as fast as if you declare them as a local.

 

Thought I would only declare functions as local if they are ONLY used for the code below or in case of onClienRender.

 


There are two variants and the main difference while using is this:

iprint(type(exampleFunction)) -- nil

local function exampleFunction ()
	iprint(type(exampleFunction)) -- function
end

iprint(type(exampleFunction)) -- function

 

iprint(type(exampleFunction)) -- nil

local exampleFunction = function ()
	iprint(type(exampleFunction)) -- nil
end

iprint(type(exampleFunction)) -- function

Fix for this one:

iprint(type(exampleFunction)) -- nil

local exampleFunction

iprint(type(exampleFunction)) -- nil


exampleFunction = function ()
	iprint(type(exampleFunction)) -- function
end

iprint(type(exampleFunction)) -- function

 

For more information:

https://www.lua.org/pil/6.2.html

 

 

Edited by IIYAMA
  • Like 1
  • Thanks 1
Link to comment
  • 3 weeks later...

Hey again, can someone say if these loops are identical?

local t = {}
for k, v in pairs(theTable) do
	if type(v) == "table" then
		t[k] = table.copy(theTable)
	else
		t[k] = v
	end
end
local t = {}
for i = 1, #theTable do
	if type(theTable[i]) == "table" then
		t[i] = table.copy(theTable)
	else
		t[i] = theTable[i]
	end
end

I want to make all loops like the second one to get better performance but am not sure if they'll function the same.

On 10/8/2017 at 01:12, quindo said:

In reality you shouldn't bother with such micro optimizations if you aren't traversing tables with thousands of elements pretty often.

Would it be worth it to edit all 'for' loops of my server's resources (around 100) or performance would still remain the same in reality? They only go through small-ish tables, nothing huge.

Edited by koragg
Link to comment

Not really the same, pairs loop can iterate over unordered tables, so if you have something like 
 

local table = {
	["item"] = val1,
	["item2"] = val2,
	["item3"] = val3
}

Then you will be able to iterate over it only using pairs()

for i,#table do can iterate only over tables like this:
 

local table = {
  	[1] = val1,
  	[2] = val2,
  	[3] = val3
  }

 

  • Thanks 1
Link to comment
  • Moderators

+

As the pairs loop can iterate over all kinds of keys, it might not loop the items in order.

local table = {
	"item1",
	"item2",
	"item3"
}

for key, data in pairs(table) do 
	iprint(data)
end

 

The result could be:

item2

item3

item1

 

 


  • Thanks 1
Link to comment
  • Moderators

Want to learn some more?

 

Did you ever tried to remove multiple items from a table using table.remove?

If not, try it and see what happens. I will provide you with a solution to an issue you will encounter.

 

Give it 10 items and remove 3 or more of them with your own conditions. Make sure that atleast two items are placed next to each other.

 

Debug the table at the end.

iprint(table)

Link to comment
5 hours ago, IIYAMA said:

Want to learn some more?

 

Did you ever tried to remove multiple items from a table using table.remove?

If not, try it and see what happens. I will provide you with a solution to an issue you will encounter.

 

Give it 10 items and remove 3 or more of them with your own conditions. Make sure that atleast two items are placed next to each other.

 

Debug the table at the end.

iprint(table)

I've never worked with tables that much to be honest. Just wanted to try optimise my server a bit for potato pcs. But will try this, sounds good to know for my university, even though it's C++ there. 

  • Like 1
Link to comment

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...