I’m not sure why you’re assuming that but I can help you understand how it actually works.
As you might know a few years ago there was an announcement about how Vector3 was added as a built-in type. This specifically mentioned that it was already added to Luau for a while, but Roblox just hasn’t been using it with Vector3 yet:
Internally, our VM has supported a built-in ‘vector’ value type for some time now with built-in vector operations, but the Roblox Vector3 userdata class didn’t use that machinery.
Luau currently does not allow you to create this internal data type as it does not offer a standard library yet for constructing this data type. Though internal functions for doing so do exist, as you can find in the language’s source code
This constructs an object without any metatables directly attached. Roblox attaches a metatable to all vectors initially by doing a single internal setmetatable call on a vector all the way at the start, which causes the global metatable for all vector types to be set to whatever metatable Roblox passes. Because this metatable is global, no other setmetatable calls are required to add the behavior required to make vectors work like they do in Roblox. That’s just because only tables and userdata can have their own metatable, all other data types share a single global metatable.
Now to explain why your benchmark code is giving different results, I’ll just give you my benchmark so you can test it for yourself. I rewrote it quickly with some comments to explain certain decisions since I’m not home right now.
my benchmark code
--!optimize 2
local ITERATIONS = 1e8
local function testNumber()
-- define the numbers in such a way that luau considers them "variable" instead of constant
-- this would normally be optimized which isn't realistic for a real world scenario
local x, y; x, y = 0, 0
local ox, oy; ox, oy = 1, 1
for i = 1, ITERATIONS do
x = x + ox
y = y + oy
x = x - ox
y = y - oy
x = x * ox
y = y * oy
x = x / ox
y = y / oy
end
return x, y
end
local function testVector()
-- because
local vec; vec = Vector3.new(0, 0)
local vecO; vecO = Vector3.new(1, 1)
for i = 1, ITERATIONS do
vec = vec + vecO
vec = vec - vecO
vec = vec * vecO
vec = vec / vecO
end
return vec
end
local function bench(name, func)
local start = os.clock()
func()
local time = os.clock() - start
print("benchmarking " .. name)
print(string.format("\tresult: %-.2f nanoseconds", time / ITERATIONS * 1_000_000_000))
end
bench("number", testNumber)
bench("vector", testVector)
These are my results: