2013-02-14 23 views
2

我在LuaJIT工作,有我所有的圖書館和諸如此類的東西保存「foo」的裏面,像這樣:全局變差,這是否會以任何方式提高性能?

foo = {}; -- The only global variable 
foo.print = {}; 
foo.print.say = function(msg) print(msg) end; 
foo.print.say("test") 

現在我在想,會使用元表,並保持所有的圖書館本地幫助呢?或者這不重要。我的想法是這樣的:

foo = {}; 
local libraries = {}; 

setmetatable(foo, { 
    __index = function(t, key) 
     return libraries[key]; 
    end 
}); 

-- A function to create a new library. 
function foo.NewLibrary(name) 
    libraries[name] = {}; 

    return libraries[name]; 
end; 

local printLib = foo.NewLibrary("print"); 

printLib.say = function(msg) print(msg) end; 

-- Other file: 
foo.print.say("test") 

我真的沒有工具的基準此權利,但將在所有維持圖書館的實際內容在本地表提高性能?即使是最輕微的?

我希望我在這方面明確mysef,基本上我想知道的是:Performance-wise是第二種方法更好?

如果有人可以鏈接/詳細解釋如何在Lua中處理全局變量,這可以解釋這一點,那也很好。

回答

2

真的沒有工具來此基準現在

當然你怎麼做。

local start = os.clock() 
for i=1,100000 do -- adjust iterations to taste 
    -- the thing you want to test 
end 
print(os.clock() - start) 

有了性能,你幾乎總是想要基準。

會保持庫中的實際內容在本地表中增加性能嗎?

與第一版本的代碼相比?理論上沒有。

你的第一個例子中(剔除不必要的克魯夫特):

foo = {} 
foo.print = {} 
function foo.print.say(msg) 
    print(msg) 
end 

爲了讓您的打印功能需要三個表查詢:

  1. 指數_ENV與 「富」
  2. 指數foo帶有「打印」的表格
  3. 索引foo.print帶有「說」的表格。

你的第二個例子:

local libraries = {} 
libraries.print = {} 
function libraries.print.say(msg) 
    print(msg) 
end 

foo = {} 
setmetatable(foo, { 
    __index = function(t, key) 
     return libraries[key]; 
    end 
}); 

爲了讓您的打印功能現在需要五個表查找與其他額外的工作一起:

  1. 指數_ENV與 「富」
  2. 指數foo表「打印」
  3. Lua中發現的結果是零,檢查是否foo有一個元表,找到一個
  4. 指數的metatable與「__index」
  5. 檢查,看結果是否是在表或函數,Lua中找到它的一個功能,所以它的關鍵
  6. 指數libraries與調用它「打印」
  7. 指數print表「說」

一些這些額外的工作是在C代碼中完成的,因此這將是速度比,如果這一切都是在Lua實現的,但它肯定需要更多時間。

標杆使用環路I以上表明,第一個版本是大致兩倍快於香草Lua中的第二個。在LuaJIT中,兩者速度完全相同。很明顯,差異在LuaJIT的運行時間中得到了優化(這非常令人印象深刻)。只是去顯示基準是多麼重要。


旁註:Lua中允許您提供一個表__index,這將導致查找相當於你的代碼:

setmetatable(foo, { __index = function(t, key) return libraries[key] end }) 

所以,你可以這樣寫:

setmetatable(foo, { __index = libraries }) 

這也正好快得多。

+0

感謝這個有用的信息,但在側面說明,我知道我可以提供一個表__index,但你會在哪裏得到的鑰匙? 此外,我可能只是用簡單的代碼去看看你展示的所有麻煩。 – TheJjokerR 2013-02-15 09:20:02

+0

等待不要忘記,你從側面註釋中刪除[鍵]部分,它會按預期工作。沒有看到。 – TheJjokerR 2013-02-15 09:44:42

+0

對,對不起。錯字。 – Mud 2013-02-15 17:37:41

1

這裏是我寫我的模塊:

-- foo.lua 
local MyLib = {} 

function MyLib.foo() 
    ... 
end 

return MyLib 

-- bar.lua 
local MyLib = require("foo.lua") 
MyLib.foo() 

注意,return MyLib不在功能。 require捕獲此返回值並將其用作庫。這樣,就沒有全局變量。

相關問題