Yes, I can definitely change it to use strings just by changing the keys from numbers to strings. I would be completely okay with using .a / .b / .c because there would only be a few dozen unique field names (compared to 900.) I have a few hacky classes that reuse the table in other ways (like using the end as an array, or string keys as a lookup) so I’d need to look at it case by case.
I’ve done performance tests in the past on using the array part vs the hash part, and I remember access performance being better on string-based tables, but allocation performance and memory usage being better for array-based tables.
Here’s an allocation performance test from today. The results are pooled from the clients of a few random people who joined my profiling place over the course of an hour.
It takes 0.65x the time to create an array-based object with 8 keys compared to a name-based one. It’s not a real-world test, and pushing the VM this hard might affect the results, but that’s still a very real difference that can affect how many objects I can create before causing a frame spike. Although it’s interesting that {A = v}
is slightly faster than {v}
.
Source for tests
local profiles = {}
local newTest = function(create)
return function(count, spoof)
local v = spoof(nil) -- v is always nil, but the VM doesn't know that.
local clock0 = os.clock()
for _ = 1, count do
local t = create(v)
if v then t = spoof(t, v); end
end
local clock1 = os.clock()
return clock1 - clock0
end
end
local add = function(name, create)
table.insert(profiles, {
LocalName = "create/" .. name,
Test = newTest(create),
TestControl = newTest(function(v)
return v
end),
})
end
add("0", function(v)
return {}
end)
do
local mt = {
__index = {A = 1}
}
add("0(metatable)", function(v)
return (setmetatable({}, mt))
end)
end
add("a1", function(v)
return {v}
end)
add("h1", function(v)
return {A = v}
end)
add("a2", function(v)
return {v, v}
end)
add("h2", function(v)
return {A = v, B = v}
end)
add("a4", function(v)
return {v, v, v, v}
end)
add("h4", function(v)
return {A = v, B = v, C = v, D = v}
end)
add("a8", function(v)
return {v, v, v, v, v, v, v, v}
end)
add("h8", function(v)
return {A = v, B = v, C = v, D = v, E = v, F = v, G = v, H = v}
end)
add("a16", function(v)
return {
v, v, v, v, v, v, v, v,
v, v, v, v, v, v, v, v
}
end)
add("h16", function(v)
return {
A = v, B = v, C = v, D = v, E = v, F = v, G = v, H = v,
I = v, J = v, K = v, L = v, M = v, N = v, O = v, P = v,
}
end)
return {ProfileList = profiles}