local time = 5e6;
local str = "abcd";

local hold = "ABCD"; -- so initial allocations don't hurt timings

-- Enforcing scope
do

local function a()
  for i = 1, time do 
    string.upper(str);
  end
end

local string = string;

local function b()
  for i = 1, time do
    string.upper(str);
  end
end

local upper = string.upper;

local function c()
  for i = 1, time do
    upper(str);
  end
end

local function d()
  for i = 1, time do
    str:upper();
  end
end

local clock = os.clock;

local t = clock()
a()
print("a = ", clock() - t)


local t = clock()
b()
print("b = ", clock() - t)

local t = clock()
c()
print("c = ", clock() - t)

local t = clock()
d()
print("d = ", clock() - t)

end -- End scope

print"Extending string module..."

setmetatable(string, {
  __index = {
    tohex = string.upper,
  },
});

do -- scope...

local function a()
  for i = 1, time do 
    string.tohex(str);
  end
end

local string = string;

local function b()
  for i = 1, time do
    string.tohex(str);
  end
end

local tohex = string.tohex;

local function c()
  for i = 1, time do
    tohex(str);
  end
end

local function d()
  for i = 1, time do
    str:tohex();
  end
end

local clock = os.clock;

local t = clock()
a()
print("a = ", clock() - t)


local t = clock()
b()
print("b = ", clock() - t)

local t = clock()
c()
print("c = ", clock() - t)

local t = clock()
d()
print("d = ", clock() - t)

end -- scope
