Differences between in pairs and in next (?)

Good morning / Good evening,

This topic has been covered before though,

I put the question mark in bracketing because it seems to me that :

for _, v in next -- Fast execution

for _, v in pairs -- Slow execution

Am I wrong ?

Thx for your help :slight_smile:

the next keyword is used in loops as a function to provide that aforementioned loop with it’s variables. If you go to the lua website, pairs is actually just a function which returns next and 2 other variables. Now, they’re not exactly faster than each other, and even so the difference would be in nanoseconds, but rather just how they’re used.

I totally agree with the return of the function. However here is the script that I found (I modified it to better fit my future script).

Here it is :

local Home = script.Parent
local Supports = Home:WaitForChild("Supports")
local Swing1 = Home:WaitForChild("Swing1")

-- Variables
local Frame = Home:WaitForChild("Frame")

local Hook1 = Swing1:WaitForChild("Hook1")
local Hook2 = Swing1:WaitForChild("Hook2")
local SwingSeat1 = Swing1:WaitForChild("SwingSeat1")
local SwingMesh1 = Swing1:WaitForChild("SwingMesh1")

local RopeSupport1 = Supports:WaitForChild("RopeSupport1")
local RopeSupport2 = Supports:WaitForChild("RopeSupport2")
local RopeSupport3 = Supports:WaitForChild("RopeSupport3")
local RopeSupport4 = Supports:WaitForChild("RopeSupport4")

-- Autres
local CurrentOccupant = nil
local Vector3New,CFrameNew,CFrameAngles,MathRad,MathAbs = Vector3.new,CFrame.new,CFrame.Angles,math.rad,math.abs

-- Paramètres
local Configuration = Home:WaitForChild("Configuration")
local SwingPower = Configuration:WaitForChild("SwingPower")

local function SetPhysicalProperties(Part,Density)
	if Part then
		Part.CustomPhysicalProperties = PhysicalProperties.new(Density,Part.Friction,Part.Elasticity)
	end
end

GetAllDescendants = function(instance, func)
	func(instance)
	for _, child in next, instance:GetChildren() do
		GetAllDescendants(child, func)
	end
end

local function SetCharacterToWeight(ToDensity,Char)
	GetAllDescendants(Char,function(d)
		if d and d.Parent and d:IsA("BasePart") then
			SetPhysicalProperties(d,ToDensity)
		end
	end)
end

local function OnSeatChange(Seat)
	if Seat.Occupant then
		local CurrentThrottle = Seat.Throttle
		local BodyForce = Seat:WaitForChild("BodyForce")
		
		-- Ajuste balancement quand Utilisé.
		-- Peut également être modifié dans Configuration -> SwingPower.
		if CurrentThrottle == 1 then
			BodyForce.Force = Seat.CFrame.lookVector * SwingPower.Value * 100
		elseif CurrentThrottle == -1 then
			BodyForce.Force = Seat.CFrame.lookVector * SwingPower.Value * -100
		else
			BodyForce.Force = Vector3New()
		end
		
		delay(0.2,function()
			BodyForce.Force = Vector3New()
		end)
		
		-- Modification apesanteur Charactère.
		if CurrentOccupant == nil then
			CurrentOccupant = Seat.Occupant
			SetCharacterToWeight(0,CurrentOccupant.Parent)
		end
		
	elseif CurrentOccupant then
		-- Réin. poids Charactère.
		SetCharacterToWeight(0.7,CurrentOccupant.Parent)
		CurrentOccupant = nil
	end
end

SwingSeat1.Changed:connect(function()
	OnSeatChange(SwingSeat1)
end)

Line 32 :

GetAllDescendants = function(instance, func)
	func(instance)
	for _, child in next, instance:GetChildren() do
		GetAllDescendants(child, func)
	end
end

local function SetCharacterToWeight(ToDensity,Char)
	GetAllDescendants(Char,function(d)
		if d and d.Parent and d:IsA("BasePart") then
			SetPhysicalProperties(d,ToDensity)
		end
	end)
end

After doing the test several times (next vs pairs), SetCharacterToWeight (I think) requires 3/4x more time before being optimal. It is no longer in nanoseconds but in seconds. :confused:

Vidéos :

With in next :

Innext.wmv (2.0 MB)

With in pairs :

Inpairs.wmv (3.1 MB)

From the tests I just ran with a simple double upvalue change, the results for both pairs and next are near indistinguishable. I’m not quite sure why your program is suffering such significant performance issues with what I found to be a small difference, which if you were wondering was about 0.000001487.

I redid the test again to see and it takes me x5 more time to arrive at the final result (to be at the top with the swing)

Next : 8 use of up and down keys

Pairs : 40 use of up and down keys

I’m confused I don’t know where the problem comes from :confused:

Here is the Swing Swing Set - Roblox

If after trying it you see no difference then I have another problem.

pairs and ipairs have both been optimised in Luau. pairs is more idiomatic and readable if you’re iterating through a dictionary so you should probably go with that over in next. While in next does function like pairs it’s not readable and serves better use cases like controlled iteration in a while loop.

1 Like

I went to see why next in this case is faster than pairs. Opinions differ but overall next should not be present for such a minor problem. So I changed that to :

local function GetAllDescendants(instance, func)
	func(instance)
	for _, child in pairs, instance:GetChildren() do
		GetAllDescendants(child, func)
	end
end

And :

			BodyForce.Force = Seat.CFrame.lookVector * SwingPower.Value * 500 -- old value = 100
		elseif CurrentThrottle == -1 then
			BodyForce.Force = Seat.CFrame.lookVector * SwingPower.Value * -500 -- old value = -100

However, I’m still confused about the use of next.

Thank you @Benified4Life and @colbert2677 for your informations :slight_smile: