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")

現在、これをベンチマークするツールは実際にはありませんが、ライブラリの実際のコンテンツをローカルテーブルに保持すると、パフォーマンスがまったく向上しますか? 少しでも?

基本的に私が知りたいのは、次のことだけです。パフォーマンスに関しては、2番目の方法の方が優れていますか?

誰かがLuaでグローバル変数がどのように処理されるかについてリンク/詳細な説明を与えることができれば、これを説明することができればそれも素晴らしいでしょう.

4

2 に答える 2

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

print 関数を取得するには、3 つのテーブル ルックアップが必要です。

  1. index _ENV with "foo"
  2. foo「print」付きのインデックステーブル
  3. foo.print「say」付きのインデックステーブル。

2番目の例:

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

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

print 関数を取得するには、5 つのテーブル ルックアップとその他の追加作業が必要になります。

  1. index _ENV with "foo"
  2. foo「print」付きのインデックステーブル
  3. Luaは結果がnilであることを発見し、メタテーブルがあるかどうかを確認しfoo、メタテーブルを見つけます
  4. 「__index」でメタテーブル化可能なインデックス
  5. 結果がテーブルまたは関数であるかどうかを確認します。Luaはそれが関数であるため、キーで呼び出します
  6. libraries「印刷」のある索引
  7. print「say」でテーブルにインデックスを付ける

この余分な作業の一部は C コードで行われるため、これをすべて Lua で実装した場合よりも高速になりますが、時間がかかることは間違いありません。

上で示したループを使用したベンチマークでは、最初のバージョンはバニラ Lua の 2 番目のバージョンの約 2 倍の速さです。LuaJIT では、どちらもまったく同じ速度です。明らかに、違いは LuaJIT の実行時に最適化されます (これは非常に印象的です)。ベンチマークがいかに重要かを示しています。


補足: Lua を使用すると、 のテーブルを指定できます__index。これにより、コードと同等のルックアップが得られます。

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

したがって、次のように書くことができます。

setmetatable(foo, { __index = libraries })

これはまた、はるかに高速です。

于 2013-02-14T20:07:58.500 に答える
1

モジュールの書き方は次のとおりです。

-- foo.lua
local MyLib = {}

function MyLib.foo()
    ...
end

return MyLib

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

return MyLibは関数ではないことに注意してください。requireこの戻り値をキャプチャし、ライブラリとして使用します。このように、グローバルはありません。

于 2013-09-05T21:49:37.030 に答える