Should I use table.foreachi() or a foor loop? (Performance wise)

I need to transfer a table into another table.
The table only has values.
It needs to be in order.

local Table = {1,2,"b", "a"} --example, has strings and number.

Edit:
In Release Notes for 566 | Roblox Creator Documentation table.foreach I has been deprecated and for loops are recommended.

Why not try both and measure the time each one takes?

Is there a way to limit ram usage, I think my other background tasks would interfere.

They shouldn’t and if they do they should affect both tests equally, so it wont matter as long as you compare the results to each other. Also I have a section in this post on how to set this kind of test up (towards the end): Proactive Testing: Profiling, Unit, and Fuzz testing

1 Like

What amount of values would you recommend?

You should run each function enough times to take about one second total. The more times you run it the more precise the average will be. You should also try to do each run with different inputs, otherwise the result may be misleadingly faster. I will try and make an example of this.

Can I also add the values using code (the same for booth functions) or do I have to hard code them?

Studio doesn’t like 1,000,000 numbers in a table. (At least the amount to make it take 1+ second.

You can add them using code just dont time that part.

ServerScriptService.Script:12: table overflow ):
Will have to shorten it take to under a second.
Trying 100,000 now.
Trying 10,000 now.

Does not even allow me to add 10,000 values.
Not sure if it is even possible to test that low.

Here is a test I wrote:

local debugTools = require(game:GetService("ReplicatedStorage"):WaitForChild("DebugTools"))

local numberOfTestInputs = 1000
local numberOfTestRuns = 10000000
local testVectors = {}
local testOutput = {}

--Generate 1000 example inputs
for i = 1, numberOfTestInputs do
	local newTable = {}
	
	local number = math.random(1, 1000)
	
	if math.random(1,2) == 2 then
		table.insert(newTable, tostring(number))
	else
		table.insert(newTable, number)
	end
	
	table.insert(testVectors, newTable)
end

local function CopyFor()
	local output = {}
	local input = testVectors[math.random(1, numberOfTestInputs)]
	
	for i, v in ipairs(input) do
		output[i] = input[i]
	end
	
	table.insert(testOutput, output)
end

local function CopyForeachi()
	local output = {}
	local input = testVectors[math.random(1, numberOfTestInputs)]
	
	table.foreachi(input, function(i, v)
		output[i] = v
	end)
	
	table.insert(testOutput, output)
end

local function CopyClone()
	local input = testVectors[math.random(1, numberOfTestInputs)]
	local output = table.clone(input)
	
	table.insert(testOutput, output)
end

local tstart = tick()

for i = 1, numberOfTestRuns do
	CopyFor()
end

local ttotal = tick() - tstart

print("Time to run CopyFor " ..numberOfTestRuns.. " times: " ..ttotal)

--Clear table
testOutput = {}

tstart = tick()

for i = 1, numberOfTestRuns do
	CopyForeachi()
end

ttotal = tick() - tstart

print("Time to run CopyForeachi " ..numberOfTestRuns.. " times: " ..ttotal)

testOutput = {}

tstart = tick()

for i = 1, numberOfTestRuns do
	CopyClone()
end

ttotal = tick() - tstart

print("Time to run CopyClone " ..numberOfTestRuns.. " times: " ..ttotal)

Outputs:



So table.clone is the fastest?
Didn’t even know that existed.

The results say its the fastest but it doesn’t let you do things on the values as you copy it, so if you only need to copy its the fastest way. The other two would let you check the value and do some extra operation on it as you copy.

1 Like

Do you know if it is still the fastest if it needs to be copied to a table that already has values?

It should still be the fastest way but there will be a tiny bit of extra performance required to garbage collect the replaced tables. This cost is hard to measure and probably will be the same for each method. The difference is likely to be very small compared to other performance costs in your game.

FYI table.foreachi and table.foreach are both deprecated (or in the process of being deprecated). If you didn’t want to use table.clone and wanted a loop for something else:

for index, value in table do

…should be the fastest way to do it.

2 Likes

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