只要實戰(zhàn)不說廢話
變量
因為 Lua 的寄存器很多,預(yù)編譯時便能將所有的局部變量存到寄存器中。所以,在 Lua 中訪問局部變量是很快的。所以解決Lua性能問題,最重要的是用 local
去修飾變量。不使用 local
修飾的變量都是全局變量,在查詢局部變量的時候要去全局表 _G
中查詢,很耗時間。
除了這個明顯的地方,另有幾處也可使用局部變量,可以助你擠出更多的性能。比如,如果在很長的循環(huán)里調(diào)用函數(shù),可以先將這個函數(shù)賦值給一個局部變量。這個代碼:
for i = 1, 1000000 do
local x = math.sin(i)
end
下面的方法比上面的方法快30%
local sin = math.sin
for i = 1, 1000000 do
local x = sin(i)
end
訪問外層局部變量(也就是外一層函數(shù)的局部變量 up Value)并沒有訪問局部變量快,但是仍然比訪問全局變量快。訪問速度是這樣的:first Value > up Value > global
考慮如下代碼:
function foo(x)
for i = 1, 1000000 do
x = x + math.sin(i)
end
return x
end
我們可以通過在 foo函數(shù)外面定義一個 sin來優(yōu)化它:(local sin
就相當于 function foo
的 up Value
)
local sin = math.sin
function foo(x)
for i = 1, 1000000 do
x = x + sin(i)
end
return x
end
print(foo(10))
表
當 Lua 想在表中插入一個新的鍵值而哈希數(shù)組已滿時,Lua 會做一次重新哈希(rehash),我們以往寫程序的習(xí)慣是這么初始化表 a = {}
這個時候 Lua 是沒有給 table
分配空間的。如果是下面的代碼會發(fā)生什么:
local a = {}
for i =1, 3 do
a[i] = true
end
這段代碼觸發(fā)了兩次 rehash (一次分配2的指數(shù)值大小),如果是處理一個大數(shù)據(jù),需要幾萬次的循環(huán),可想而知 rehash 的次數(shù)將非常大,所以這樣大大浪費了空間和性能。以后初始化表的時候如果如果知道表中有固定的值了,就直接構(gòu)造進去。比如:
a = {true, true, true}
for i = 1, 1000000 do
local a = {}
a [1] = 1; a[2] = 2; a[3] = 3
end
這段代碼運行了2.0s
其他
可以把不變的操作放在循環(huán)外
function foo (...)
for i = 1, n do
local t = {1, 2, 3, "hi"}
-- 做一些不改變 t 的操作
...
end
end
local t = {1, 2, 3, "hi"} -- 一次性地創(chuàng)建 t
function foo (...)
for i = 1, n do
-- 做一些不改變 t 的操作
...
end
end
很多字符串的處理,都可以通過在現(xiàn)有字符串上使用下標,來避免創(chuàng)建不必要的新字符串。例如,函數(shù) string.find
返回的是給定模式出現(xiàn)的位置,而不是一個與之匹配的字符串。返回下標,就避免了在成功匹配時創(chuàng)建一個新的子字符串。若有需要,可以再通過函數(shù) string.sub
來獲取匹配的子字符串。