Which one is faster? rawset() or table.insert()

I searched for information about this topic from chatgpt and it said that rawset() is quicker than table.insert(). I wanna confirm which one is actually quicker. :pray:

1 Like

Apparently rawset() is faster!

image

Script I used
local x = 0
for _ = 1,2000 do
	local t = os.clock()
	local _t = {}
	for i = 1,1000 do
		table.insert(_t,i,math.random())
	end
	local dt = os.clock()-t
	x += dt
end
warn("average table.insert() time:", x/2000)
local y = 0
for _ = 1,2000 do
	local t = os.clock()
	local _t = {}
	for i = 1,1000 do
		rawset(_t,i,math.random())
	end
	local dt = os.clock()-t
	y += dt
end
warn("average rawset() time:      ", y/2000)
--I'm not 100% sure if this is the correct way to compare them tho
2 Likes

Acording to my code its about the same amount

image

Heres my code

local Mt1 = {}
local Mt2 = {}

local InsertStart = tick()

table.insert(Mt1,1,1)

local InsertEnd = tick()
print("Insert Took", (InsertEnd - InsertStart) * 1000, "Miliseconds")

local RawsetStart = tick()

rawset(Mt2,1, 1)

local RawsetEnd = tick()
print("Rawset Took", (RawsetEnd -  RawsetStart)* 1000, "Miliseconds")
1 Like

I have another question, do you recommend rawset more or table insert? Because I’ve seen many people use table insert rather than using the rawset. (not including t[num] or something.)

I personally use table.insert() as the speed difference between the two is very small and it doesn’t really change much :​P

Me personaly I dont know the difference between them quite yet. Looking into it as I’m not quite familiar with what the difference is between table.insert() and rawset() is. It seems that it is much more direct and lower level, meaning some steps are skipped when setting data. this is the forum post that I’m getting My sources

As far as I’m aware the two are practically the same they just work differently under the hood.

Specifying an index to insert is what is slowing your code down. If you don’t need to specify an index and just want to insert at the end of the table, you should use table.insert and omit the position argument.

See

specifically,

When appending elements to tables, it’s recommended to use table.insert (which is the fastest method to append an element to a table if the table size is not known)

If you know the size of your array, you can speed up inserting into your array by pre-allocating it via table.create (doing this actually makes rawset slower than t[i] = rnd)

If you need to move elements up, using table.insert is faster than both moving the elements up one via t[k] = v then setting it as well as rawset(t, k, v) (t[k] = v is a smidgeon faster than rawset though)

Tests

1:

--[[
This file is for use by Benchmarker (https://boatbomber.itch.io/benchmarker)

|WARNING| THIS RUNS IN YOUR REAL ENVIRONMENT. |WARNING|
--]]

return {
	ParameterGenerator = function()
		return
	end;

	Functions = {
		["insert(t, i, random)"] = function(Profiler)
			local t = {}
			
			for i = 1, 1000 do
				table.insert(t, i, math.random())
			end
		end,

		["insert(t, random)"] = function(Profiler)
			local t = {}
			
			for i = 1, 1000 do
				table.insert(t, math.random())
			end
		end,
		
		["rawset(t, i, random)"] = function(Profiler)
			local t = {}
			
			for i = 1, 1000 do
				rawset(t, i, math.random())
			end
		end;
		
		["t[i] = random"] = function(Profiler)
			local t = {}
			
			for i = 1, 1000 do
				t[i] = math.random()
			end
		end,
	},
}

2:

--[[
This file is for use by Benchmarker (https://boatbomber.itch.io/benchmarker)

|WARNING| THIS RUNS IN YOUR REAL ENVIRONMENT. |WARNING|
--]]

return {
	ParameterGenerator = function()
		return
	end;

	Functions = {
		["table.create(1000), t[i] = rnd"] = function(Profiler)
			local t = table.create(1000)
			
			for i = 1, 1000 do
				t[i] = math.random()
			end
		end,
		
		["table.create(1000), rawset(t, i, rnd)"] = function(Profiler)
			local t = table.create(1000)
			
			for i = 1, 1000 do
				rawset(t, i, math.random())
			end
		end,
	},
}

3:

--[[
This file is for use by Benchmarker (https://boatbomber.itch.io/benchmarker)

|WARNING| THIS RUNS IN YOUR REAL ENVIRONMENT. |WARNING|
--]]

return {
	ParameterGenerator = function()
		return
	end;

	Functions = {
		["insert(t, 1, random)"] = function()
			local t = {}
			
			for i = 1, 1000 do
				t[i] = math.random()
			end
			
			table.insert(t, 1, t[i])
		end;
		
		["t[1] = random"] = function()
			local t = {}

			for i = 1, 1000 do
				t[i] = math.random()
			end

			for i = 1000, 1, -1 do
				t[i + 1] = t[i]
			end

			t[1] = math.random()
		end;
		
		["rawset(t, i, random)"] = function()
			local t = {}

			for i = 1, 1000 do
				t[i] = math.random()
			end

			for i = 1000, 1, -1 do
				rawset(t, i + 1, t[1])
			end

			rawset(t, 1, math.random())
		end;
	},
}

TLDR:
table.insert is fastest when appending to a variable size array
t[k] = v is fastest when overwriting an index or using a pre-allocated array
table.insert(t, k, v) is fastest if you need the subsequent elements to be moved up
rawset should only be used for metatables

1 Like