How inefficient really is "for pairs?"

Hi, I’m working on a few things that use a lot of pairs and loops. I was wondering, how inefficient is pairs? Is it worth it to find better more efficient work-arounds? If anybody knows how it would effect the performance to have a lot of pairs please let me know.

1 Like

They are both extremely close in comparison, so you shouldn’t be worrying about minor things like that.

There is a third option you didn’t mention though, which is generalized iteration. Generalized iteration is much faster and more performant, so you should be using it from now on. The performance difference is negligible though, so there’s no use changing your existing code base, just keep it in mind for later.

Example:

for i, object in workspace:GetChildren() do
2 Likes

I looked into this when Generalized Iteration was first released: https://devforum.roblox.com/t/what-are-some-optimizations-roblox-scripters-should-know-about-like-taskwait-instead-of-wait/1803558/50

Generalized iteration is slightly slower than both pairs and ipairs. But all are faster than next; and next is faster than manually indexing over each element.

None of these performance differences are notable enough to be worth considering, however.

Honestly, I wouldn’t be surprised either way. There was a time when next was faster than pairs–goes to show how little these considerations actually matter.

2 Likes

Generalized iteration is faster than both (around 1.5x faster in my tests, but varies depending on table size), you should try testing it again.

Edit: I’ve tested with way higher sizes and I’ve realized that the speeds were similar, so you were semi-right.

1 Like

I just did some testing and it seems like pairs is the best option overall. There were many close ties though, so I don’t think it matters too much.

image
image
image

Some of the tests I did had ipairs in second or first place.

the script i made, please tell me if my results are innacurate

yes, i know how messy it is in some areas

local Table = {
	"236";
	"rehyer";
	"238";
	"rehye";
	"26";
	"rehyer";
	"36";
	"ryer";
	"265";
	"rhyer";
	"236";
	"rehyer";
	"238";
	"rehye";
	"26";
	"rehyer";
	"36";
	"ryer";
	"265";
	"rhyer";
	game.Workspace;
}

local function Test()
	local Results = {
		[1] = {
			name = "pairs";
			value = 0
		};
		[2] = {
			name = "ipairs";
			value = 0
		};
		[3] = {
			name = "none";
			value = 0
		};
	}

	local ST1 = os.clock()
	for _, v in Table do					--None
		--print(v)
	end
	local Result1 = os.clock() - ST1
	--print(Result1)
	Results[3].value = Result1


	---------------------------------------------------


	local ST2 = os.clock()
	for _, v in pairs(Table) do				--Pairs
	end
	local Result2 = os.clock() - ST2
	Results[1].value = Result2

	----------------------------------------------------
	local ST3 = os.clock()
	for _, v in ipairs(Table) do			--Ipairs
		
	end
	local Result3 = os.clock() - ST3
	Results[2].value = Result3
	
	table.sort(Results, function(a, b)
		return a.value < b.value
	end)
	
	return Results
end

task.wait(1)

--[[local Res1 = Test()
local Res2 = Test()
local Res3 = Test()
local Res4 = Test()
local Res5 = Test()
local Res6 = Test()


--
print("RESULTS")
print("Test 1")
print(Res1)
print("Test 2")
print(Res2)
print("Test 3")
print(Res3)
print("Final results: ")
print("Test 4")
print(Res4)
print("Test 5")
print(Res5)
print("Test 6")
print(Res6)
print("Final results: ")
print(Res1[1].name)
print(Res2[1].name)
print(Res3[1].name)
print(Res4[1].name)
print(Res5[1].name)
print(Res6[1].name)
]]

--
local None = 0
local Pairs = 0
local Ipairs = 0

for i = 1, 300 do
	local Res = Test()
	if Res[1].name == "pairs" then
		Pairs += 1
	elseif Res[1].name == "ipairs" then
		Ipairs += 1
	elseif Res[1].name == "none" then
		None += 1
	end
end

print("None: "..None)
print("Pairs: "..Pairs)
print("Ipairs: "..Ipairs)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.