Module:Sandbox/Waddie96
Appearance
local iterations = 500000
local p = {}
--- Allows for consistent treatment of boolean-like wikitext input.
--- Uses lookup table, instead of if-elseif-else statement, for efficiency.
--
-- If your wiki uses non-ASCII characters for any of "yes", "no", etc., you
-- should replace "string.lower" with "mw.ustring.lower" in the
-- following line. NOTE: It is _much_ slower.
local LOWER = string.lower
local TO_NUMBER = tonumber
local TYPE = type
local CLOCK = os.clock
local BOOLEAN_MAP = {
yes = true, y = true, ['true'] = true, t = true, on = true, ['1'] = true,
no = false, n = false, ['false'] = false, f = false, off = false, ['0'] = false
}
local function table_version(value, defaultResponse)
if value == nil then
return nil
end
local valueType = TYPE(value)
if valueType == 'boolean' then
return value
elseif valueType == 'string' then
local lookupResult = BOOLEAN_MAP[LOWER(value)]
if lookupResult ~= nil then
return lookupResult
end
end
-- Numeric check works for both numbers and numeric strings.
local number = TO_NUMBER(value)
if number == 1 then
return true
elseif number == 0 then
return false
end
return defaultResponse
end
-- If-elseif chain version
local function chain_version(val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = TYPE(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'on'
or TO_NUMBER(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'off'
or TO_NUMBER(val) == 0
then
return false
else
return default
end
end
-- Benchmark helper
local function benchmark(func, name)
local test_cases = {
"yes", "off", "on", "0", "1", "true", "false", "random.5", "0.5", "1.0", "0.0",
"", "a", true, false, 1.5, 0.5
}
local start = CLOCK()
local result
for _ = 1, iterations do
for i = 1, #test_cases do
result = func(test_cases[i], true)
end
end
local elapsed = CLOCK() - start
local total_ops = iterations * #test_cases
local msg = string.format("%s took %.4f seconds for %d operations", name, elapsed, total_ops)
mw.log(msg)
return msg
end
function p.main()
mw.log(("Running benchmarks with %d iterations..."):format(iterations))
local result1 = benchmark(table_version, "Lookup table")
local result2 = benchmark(chain_version, "If-elseif chain")
return result1 .. "<br>" .. result2
end
return p