Lua FFI 實(shí)戰(zhàn) May 19, 2013由來FFI庫,是LuaJIT中最重要的一個擴(kuò)展庫。它允許從純Lua代碼調(diào)用外部C函數(shù),使用C數(shù)據(jù)結(jié)構(gòu)。有了它,就不用再像 FFI簡介FFI庫,允許從純Lua代碼調(diào)用外部C函數(shù),使用C數(shù)據(jù)結(jié)構(gòu)。 FFI庫最大限度的省去了使用C手工編寫繁重的Lua/C綁定的需要。不需要學(xué)習(xí)一門獨(dú)立/額外的綁定語言——它 FFI緊緊的整合進(jìn)了LuaJIT(幾乎不可能作為一個獨(dú)立的模塊)。JIT編譯器為Lua代碼直接訪問C數(shù)據(jù)結(jié)構(gòu)而產(chǎn)生的代碼,等同于一個C編譯器應(yīng)該生產(chǎn)的代碼。在JIT編譯過的代碼中,調(diào)用C函數(shù),可以被 這一頁將簡要介紹FFI庫的使用方法。 激勵范例:調(diào)用外部C函數(shù)真的很用容易去調(diào)用一個外部C庫函數(shù):
以上操作步驟,如下:
事實(shí)上,背后的實(shí)現(xiàn)遠(yuǎn)非如此簡單:③ 使用標(biāo)準(zhǔn)C庫的命名空間 Ok,使用
Bing! 再一次, 遠(yuǎn)非如此簡單,不? 和要求使用Lua/C API去綁定函數(shù)的努力相比:
傳統(tǒng)的處理方式
?。。ê懿凰剑。?/p> 激勵示例: 使用C數(shù)據(jù)結(jié)構(gòu)FFI庫允許你創(chuàng)建,并訪問C數(shù)據(jù)結(jié)構(gòu)。當(dāng)然,其主要應(yīng)用是C函數(shù)接口。但,也可以獨(dú)立使用。 Lua構(gòu)建在高級數(shù)據(jù)類型之上。它們很靈活、可擴(kuò)展,而且是動態(tài)的。這就是我們大家都喜歡Lua的原因所在。唉,針對特殊任務(wù),你需要一個低級的數(shù)據(jù)結(jié)構(gòu)時,這可能會低效。例如,一個超大的不同結(jié)構(gòu)的數(shù)組,需要通過一張超大的表,存儲非常多的小表來實(shí)現(xiàn)。這需要大量的內(nèi)存開銷以及性能開銷。 這里是一個庫的草圖,操作一個彩圖,以及一個基準(zhǔn)。首先,樸素的Lua版本,如下:
以上代碼,創(chuàng)建一個160.000像素的一張表,其中每個元素是一張持有4個范圍0至255的數(shù)字值的表。首先,創(chuàng)建了一張綠色斜坡的圖(1D,為了簡單化),然后進(jìn)行1000次灰階轉(zhuǎn)換操作。實(shí)在很蠢蛋,可是我需要一個簡單示例…… 以下是FFI版本代碼。其中,被修改的部分加粗標(biāo)注: ① local ffi = require("ffi")
ffi.cdef[[
typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;
]]
② local function image_ramp_green(n)
local img = ffi.new("rgba_pixel[?]", n)
local f = 255/(n-1)
③ for i=0,n-1 do
④ img[i].green = i*f
img[i].alpha = 255
end
return img
end
local function image_to_grey(img, n)
③ for i=0,n-1 do
⑤ local y = 0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue
img[i].red = y; img[i].green = y; img[i].blue = y
end
end
local N = 400*400
local img = image_ramp_green(N)
for i=1,1000 do
image_to_grey(img, N)
end
Ok, 這是不是太困難: ① 首先,加載FFI庫,聲明底層數(shù)據(jù)類型。這里我們選擇一個數(shù)據(jù)結(jié)構(gòu),持有4字節(jié)字段,每一個由 ② 通過 ③ C數(shù)據(jù)是基于0的(zero-based),所以索引必須是0 到 n-1。你可能需要分配更多的元素,而不僅簡化轉(zhuǎn)換一流代碼。 ④ 由于 ⑤ 調(diào)用 現(xiàn)在讓我們看一下主要影響的變更: 首先,內(nèi)存消耗從22M降到640K(4004004字節(jié))。少了 其次,性能:純Lua版本運(yùn)行耗時9.57秒(使用Lua解析器52.9秒),而FFI版本在我的主機(jī)上耗時0.48秒(YMMV: 因人而異)。快了 狂熱的讀者,可能注意到了為顏色將純Lua代碼版本轉(zhuǎn)為使用數(shù)組索引([1] 替換 .red, [2] 替換 .green 等)應(yīng)該更加緊湊和更快。這個千真萬確(大約 雖然最終的代碼不是慣用的,而容易出錯。它仍然沒有得到甚至接近FFI版本代碼的性能。同時,高級數(shù)據(jù)結(jié)構(gòu)不容易傳遞給別的C函數(shù),尤其是I/O函數(shù),沒有過分轉(zhuǎn)換處罰。
擴(kuò)展閱讀
安裝LuaJIT
|
|
|