garrysmod
garrysmod copied to clipboard
Add util.In( any thing, vararg values )
Allows you to check if thing is among values.
Using the function, we can do this:
local myUsergroup = 'user'
if util.In( myUsergroup, 'user', 'vip' ) then
-- ...
end
... instead of:
local allowedUsergroups = {
user = true,
vip = true,
}
local myUsergroup = 'user'
if allowedUsergroups[ myUsergroup ] then
-- ...
end
... or:
local myUsergroup = 'user'
if myUsergroup == 'user' or myUsergroup == 'vip' then
-- ...
end
Of course, the second code is faster because it performs a key lookup (which is O(1) vs. my O(n) implementation), but util.In is useful in contexts where performance is not so important
Bad naming aside,
local myUsergroup = 'user'
if table.HasValue( { 'user', 'vip' }, myUsergroup ) then
-- ...
end
I understand this is less efficient than the proposed method, but by your own admission that is not the focus here.
Not creating the table would indeed be much more efficient when JIT compiles the select calls. Not as efficient as creating a hashtable with true vals, but for dynamic vararg values, this seems like the best solution. Efficiency should be the focus of this addition.
Not sure how I can improve on my solution ( except for brandonsturgeon's suggestion). Of course, pretty much the same thing can be done using table.HasValue (honestly, I just forgot this function existed), but my method is a bit faster.
Regarding the function name - I was guided by Python syntax:
if thing in (a, b, c):
# ...
Bad naming aside,
local myUsergroup = 'user' if table.HasValue( { 'user', 'vip' }, myUsergroup ) then -- ... endI understand this is less efficient than the proposed method, but by your own admission that is not the focus here.
Yes, performance is not a focus, because in that case I will use a key lookup. However, the developed solution, although similar to table.HasValue, is slightly more optimized. In this case, I see my function as a compromise between readability and speed - we sacrifice speed for readability, but not as much as in the case of using table.HasValue
With regards to the name, util.InValues?
util.In:
sum = 0.286
avg = 0.00286
median = 0.0030000000000001
util.In2:
sum = 0.0020000000000024
avg = 2.0000000000024e-05
median = 0
function util.In2( thing, ... )
local iMax, i = select( '#', ... ), 1
::iter::
if thing == select( i, ... ) then
return true
end
i = i + 1
if i <= iMax then goto iter end
return false
end
util.In: sum = 0.286 avg = 0.00286 median = 0.0030000000000001 util.In2: sum = 0.0020000000000024 avg = 2.0000000000024e-05 median = 0function util.In2( thing, ... ) local iMax, i = select( '#', ... ), 1 ::iter:: if thing == select( i, ... ) then return true end i = i + 1 if i <= iMax then goto iter end return false end
Sample size and size of ...?
Sample size and size of
...?
lib: https://github.com/Be1zebub/Small-GLua-Things/blob/master/sh_benchmark.lua
util.In:
sum = 0.035
avg = 0.00035
median = 0
util.In2:
sum = 0.00099999999999767
avg = 9.9999999999767e-06
median = 0
benchmark("util.In", function()
a = util.In(userName, "admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", userName)
end, 1000, 100)
benchmark("util.In2", function()
a = util.In2(userName, "admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "admin", "test", "user", "admin", "test", "user", "admin", "test", "user","admin", "test", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", "user", userName)
end, 1000, 100)
table unpack
util.In:
sum = 0.113
avg = 0.00113
median = 0.0010000000000048
util.In2:
sum = 6.415
avg = 0.06415
median = 0.063000000000017
local a = false
local users = {}
local userName = "superadmin"
for i = 1, 253 do
if i % 2 == 0 then
users[i] = "admin"
else
users[i] = "user"
end
end
users[254] = 'superadmin'
benchmark("util.In", function()
a = util.In(userName, unpack(users))
end, 1000, 100)
benchmark("util.In2", function()
a = util.In2(userName, unpack(users))
end, 1000, 100)