使用Lua 局部變數來最佳化效能,同時比較局部變數和全域變數

來源:互聯網
上載者:User

標籤:


在競爭激烈的遊戲行業中,尤其頁遊,面對策劃複雜和頻繁的需求,使用指令碼可以降低難度和成本。在使用Lua的過程中,會經常訪問全域變數來作為設定檔。

在訪問全域變數時,可以通過局部變數引用全域變數來最佳化。當然,這樣的最佳化毫無意義。

Locals Vs Globals  from  http://lua-users.org/wiki/LocalsVsGlobals




Comparison between local and global variables:


Implementation: Locals index an array of registers on the stack, with hard-coded integer index (at least in the standard implementation -- LuaImplementations).
Globals index from a table (or userdata), typically with variable name string, stored as constant or variable, as the key.
實現:在Lua標準實現中,使用hard-code 整數索引在 registers on the stack 上索引局部變數。
在table或者userdata中,通過string常量或者string變數作為鍵來索引全域變數。
Performance: The above point implies that locals can be a bit faster
Still, table indexing is a fairly efficient operation in Lua (e.g. strings are interned with precomputed hash), so this point can often be ignored unless profiling indicates optimization is needed.
效能:通過實現不同,局部變數稍微比全域變數速度快。但是,在lua table中通過string來索引也是相當快。因為字串在lua中被內化,事先計算過hash值。
所以,除非在剖析最佳化效能之外,效能問題可以被忽略。
Syntax: If an environment table is set, globals can be accessed in Lua code with or without explicitly naming the environment table they come from: foo, _G.foo, or getfenv().foo (or in 5.2.0work3, _ENV.foo). 
This allows different styles of environment usage, such as in ModuleDefinition.
文法:如果環境table是一個集合,在環境table之外可以通過foo,_G.foo 或者getfenv().foo來擷取到全域變數。
但是,局部變數只能在模組定義中擷取到。
Scope: Locals are scoped within a lexical block. Globals are scoped within any number of functions assigned a given environment table at run-time.
範圍:局部變數的範圍在文法塊中。在運行時,全域變數可以在任何環境table賦值的函數中擷取。
Declaration: Locals must be explicitly declared, with local statement, to use them.
Globals can be accessed on-the-fly, even with variable name set at runtime
The list of locals is defined statically. The list of globals may be determined at run-time and can even change during program execution.
聲明:局部變數必須通過明顯的聲明去定義和使用。所有局部變數的聲明都是靜態。但是,全域變數可以在代碼執行時,動態訪問,甚至可以在運行時設定全域變數。
所有全域變數可以在運行時來決定,設定在代碼執行過程中來改變全域變數。
Standard library access: The standard library is normally exposed to a chunk via globals.
標準庫的訪問:所有Lua的標準庫都是通過全域變數暴露給使用者。
Precedence: Locals override globals.
優先權:局部變數覆蓋全域變數
Bytecode introspection: Globals are more visible in the bytecode.
Global get/sets become GETGLOBAL/SETGLOBAL opcodes with the given variable name.
It is possible to list all the globals read or written byte a compiled chunk。
Limit on number: There is a limit to the number of locals per function (MAXLOCALS, typically 200).
位元組碼內省:
全域變數在位元組碼中是可以看到的。通過制定的變數名稱,擷取或者設定全域變數變成了GETGLOBAL/SETGLOBAL 指令。
通過讀取或者寫入一個先行編譯好塊可以羅列出所有的全域變數。
數量限制:
 每一個函數中,局部變數的數量最大為200個。
 
 
Basic facts  from  Lua Performance Tips Roberto Ierusalimschy
Before running any code, Lua translates (precompiles) the source into an internal format.
This format is a sequence of instructions for a virtual machine, similar to machine code for a real CPU.
This internal format is then interpreted by C code that is essentially a while loop with a large switch inside, one case for each instruction.
    Lua在運行任何代碼之前,Lua先行編譯原始碼成為內部位元組碼格式。
位元組碼格式就是虛擬機器的序列化指定,類似於真正CPU的機器指令。內部位元組碼格式通過C語言編寫的解譯器通過一個基礎的while loop來不斷的為每一個指定執行switch。
Perhaps you have already read somewhere that, since version 5.0, Lua uses a register-based virtual machine. 
The “registers” of this virtual machine do not correspond to real registers in the CPU, because this correspondence would be not portable and quite limited in the number of registers available.
Instead, Lua uses a stack (implemented as an array plus some indices) to accommodate its registers. 
Each active function has an activation record, which is a stack slice where in the function stores its registers.
So, each function has its own registers2. 
Each function may use up to 250 registers, because each instruction has only 8 bits to refer to a register.
  自從5.0版本,Lua使用一種register-based virtual machine 虛擬機器。 “registers” 不依賴於CPU真正的指令,依賴CPU指正的registers由於registers數量限制將導致Lua的不可以移植。
相反,lua使用stack 來解決registers。每一個函數最大有250個registers,因為每一個指定僅僅有8為來執行register。
Given that large number of registers, the Lua precompiler is able to store all local variables in registers.
The result is that access to local variables is very fast in Lua. 
So, it is easy to justify one of the most important rules to improve the performance of Lua programs: use locals!
    依賴於大量的registers,Lua可以先行編譯所以的局部變數在registers中。所以,在Lua中訪問局部變數非常快速。所以,在最佳化lua效能時,一個很重要的原則是使用局部變數:使用局部變數。
If you need to squeeze performance out of your program, there are several
places where you can use locals besides the obvious ones. 
For instance, if you call a function within a long loop, you can assign the function to a local variable. For instance, the code
for i = 1, 1000000 do
local x = math.sin(i)
end
runs 30% slower than this one:
local sin = math.sin
for i = 1, 1000000 do
local x = sin(i)
end

測試代碼:

module.lua 檔案:

A =1
B =1

main.lua檔案:

print("=================================")
require("module")
local A =A
local t1 =os.clock ()


for i=1,100000000 do
    A =2
end


local t2 =os.clock ()


print("通過局部變數來最佳化全域變數的訪問:"..(t2-t1))




local t1 =os.clock ()


for i=1,100000000 do
    B =2
end


local t2 =os.clock ()
print("直接存取全域變數:"..(t2-t1))
print("=================================")


local t1 =os.clock ()
local sin = math.sin
for i = 1, 100000000 do
  local x = sin(i)
end
local t2 =os.clock ()
print("通過局部變數來最佳化全域變數的訪問:"..(t2-t1))
local t1=os.clock ()
for i=1,100000000 do
     x = math.sin(i)
end
local t2 =os.clock ()
print("直接存取全域變數:"..(t2-t1))

測試結果:

=================================
通過局部變數來最佳化全域變數的訪問:0.825
直接存取全域變數:1.961
=================================
通過局部變數來最佳化全域變數的訪問:7.017
直接存取全域變數:10.264

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

使用Lua 局部變數來最佳化效能,同時比較局部變數和全域變數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.