婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Lua性能優(yōu)化技巧(五):削減、重用和回收

Lua性能優(yōu)化技巧(五):削減、重用和回收

熱門標(biāo)簽:漳州智云呼電話機器人 個人怎么在地圖標(biāo)注需要的店鋪 冀州市地圖標(biāo)注 怎么去除地圖標(biāo)注 新岸線智能電銷機器人 武漢外呼防封系統(tǒng)多少錢 清朝地圖標(biāo)注哈爾濱 地圖標(biāo)注大廈 百度地圖標(biāo)注早餐區(qū)域

當(dāng)處理Lua資源時,我們也應(yīng)該遵循提倡用于地球資源的3R原則——Reduce, Reuse and Recycle,即削減、重用和回收。

削減是最簡單的方式。有很多方法可以避免使用新的對象,例如,如果你的程序使用了太多的表,可以考慮改變數(shù)據(jù)的表述形式。一個最簡單的例子,假設(shè)你的程序需要操作折線,最自然的表述形式是:

復(fù)制代碼 代碼如下:

polyline =
{
    { x = 10.3, y = 98.5 },
    { x = 10.3, y = 18.3 },
    { x = 15.0, y = 98.5 },
    --...
}

盡管很自然,這種表述形式對于大規(guī)模的折線來說卻不夠經(jīng)濟(jì),因為它的每個點都需要用一個表來描述。第一種替代方式是使用數(shù)組來記錄,可以省點內(nèi)存:

復(fù)制代碼 代碼如下:

polyline =
{
     { 10.3, 98.5 },
     { 10.3, 18.3 },
     { 15.0, 98.5 },
     --...
}

對于一個有一百萬個點的折線來說,這個修改可以把內(nèi)存占用從95KB降低到65KB。當(dāng)然,你需要在可讀性上付出代價:p[i].x比p[i][1]更易懂。

另一個更經(jīng)濟(jì)的做法是使用一個數(shù)組存儲所有x坐標(biāo),另一個存儲所有y坐標(biāo):

復(fù)制代碼 代碼如下:

polyline =
{
    x = { 10.3, 10.3, 15.0, ...},
    y = { 98.5, 18.3, 98.5, ...}
}

原有的
復(fù)制代碼 代碼如下:

p[i].x

現(xiàn)在變成了
復(fù)制代碼 代碼如下:

p.x[i]

使用這種表述形式,一百萬個點的折線的內(nèi)存占用降低到了24KB。

循環(huán)是尋找降低垃圾回收次數(shù)的機會的好地方。例如,如果在循環(huán)里創(chuàng)建一個不會改變的表,你可以把它挪到循環(huán)外面,甚至移到函數(shù)外作為上值。試對比:

復(fù)制代碼 代碼如下:

function foo (...)
     for i = 1, n do
          local t = {1, 2, 3, "hi"}
          -- 做一些不會改變t表的事情
          --...
     end
end


復(fù)制代碼 代碼如下:

local t = {1, 2, 3, "hi"} -- 創(chuàng)建t,一勞永逸
function foo (...)
    for i = 1, n do
        --做一些不會改變t表的事情
        --...
    end
end

相同的技巧亦可用于閉包,只要你不把它們移到需要它們的作用域之外。例如下面的函數(shù):

復(fù)制代碼 代碼如下:

function changenumbers (limit, delta)
    for line in io.lines() do
        line = string.gsub(line, "%d+", function (num)
            num = tonumber(num)
            if num >= limit then return tostring(num + delta) end
            -- 否則不返回任何值,保持原有數(shù)值
        end)
        io.write(line, "\n")
    end
end

我們可以通過將內(nèi)部的函數(shù)移到循環(huán)外面來避免為每次迭代創(chuàng)建新的閉包:

復(fù)制代碼 代碼如下:

function changenumbers (limit, delta)
    local function aux (num)
        num = tonumber(num)
        if num >= limit then return tostring(num + delta) end
    end
    for line in io.lines() do
        line = string.gsub(line, "%d+", aux)
        io.write(line, "\n")
    end
end

但是,我們不能把aux移到changenumbers函數(shù)之外,因為aux需要訪問limit和delta。

對于多種字符串處理,我們可以通過使用現(xiàn)有字符串的索引來減少對創(chuàng)建新字符串的需要。例如,string.find函數(shù)返回它找到指定模式的位置索引,而不是匹配到的字符串。通過返回索引,它避免了在成功匹配時創(chuàng)建新的字符串。當(dāng)有必要時,程序員可以通過調(diào)用string.sub來獲取匹配的子串[1]。

當(dāng)我們無法避免使用新的對象時,我們依然可以通過重用來避免創(chuàng)建新的對象。對于字符串來說,重用沒什么必要,因為Lua已經(jīng)為我們做了這樣的工作:它總是將所有用到的字符串內(nèi)部化,并在所有可能的時候重用。然而對于表來說,重用可能就非常有效。舉一個普遍的例子,讓我們回到在循環(huán)里創(chuàng)建表的情況。這一次,表里的內(nèi)容不再是不變的。通常我們可以在所有迭代中重用這個表,只需要簡單地改變它的內(nèi)容。考慮如下的代碼段:

復(fù)制代碼 代碼如下:

local t = {}
for i = 1970, 2000 do
    t[i] = os.time({year = i, month = 6, day = 14})
end

下面的代碼是等同的,但是重用了這張表:
復(fù)制代碼 代碼如下:

local t = {}
local aux = {year = nil, month = 6, day = 14}
for i = 1970, 2000 do
    aux.year = i
    t[i] = os.time(aux)
end

實現(xiàn)重用的一個尤其有效的方式是緩存化[2]。基本思想非常簡單,將指定輸入對應(yīng)的計算結(jié)果存儲下來,當(dāng)下一次再次接受相同的輸入時,程序只需簡單地重用上次的計算結(jié)果。

LPeg,Lua的一個新的模式匹配庫,就使用了一個有趣的緩存化處理。LPeg將每個模式字符串編譯為一個內(nèi)部的用于匹配字符串的小程序,比起匹配本身而言,這個編譯過程開銷很大,因此LPeg將編譯結(jié)果緩存化以便重用。只需一個簡單的表,以模式字符串為鍵、編譯后的小程序為值進(jìn)行記錄。

使用緩存化時常見的一個問題是,存儲計算結(jié)果所帶來的內(nèi)存開銷大過重用帶來的性能提升。為了解決這個問題,我們可以在Lua里使用一個弱表來記錄計算結(jié)果,因此沒有使用到的結(jié)果最終將會被回收。

在Lua中,利用高階函數(shù),我們可以定義一個通用的緩存化函數(shù):

復(fù)制代碼 代碼如下:

function memoize (f)
    local mem = {} -- 緩存化表
    setmetatable(mem, {__mode = "kv"}) -- 設(shè)為弱表
    return function (x) -- ‘f'緩存化后的新版本
        local r = mem[x]
        if r == nil then --沒有之前記錄的結(jié)果?
            r = f(x) --調(diào)用原函數(shù)
            mem[x] = r --儲存結(jié)果以備重用
        end
        return r
    end
end

對于任何函數(shù)f,memoize(f)返回與f相同的返回值,但是會將之緩存化。例如,我們可以重新定義loadstring為一個緩存化的版本:

loadstring = memoize(loadstring)
新函數(shù)的使用方式與老的完全相同,但是如果在加載時有很多重復(fù)的字符串,性能會得到大幅提升。

如果你的程序創(chuàng)建和刪除太多的協(xié)程,循環(huán)利用將可能提高它的性能。現(xiàn)有的協(xié)程API沒有直接提供重用協(xié)程的支持,但是我們可以設(shè)法繞過這一限制。對于如下協(xié)程:

復(fù)制代碼 代碼如下:

co = coroutine.create(function (f)
    while f do
        f = coroutine.yield(f())
    end
end)

這個協(xié)程接受一項工作(運行一個函數(shù)),執(zhí)行之,并且在完成時等待下一項工作。

Lua中的多數(shù)回收都是通過垃圾回收器自動完成的。Lua使用漸進(jìn)式垃圾回收器,意味著垃圾回收工作會被分成很多小步,(漸進(jìn)地)在程序的允許過程中執(zhí)行。漸進(jìn)的節(jié)奏與內(nèi)存分配的速度成比例,每當(dāng)分配一定量的內(nèi)存,就會按比例地回收相應(yīng)的內(nèi)存;程序消耗內(nèi)存越快,垃圾回收器嘗試回收內(nèi)存也就越快。

如果我們在編寫程序時遵循削減和重用的原則,通常垃圾回收器不會有太多的事情要做。但是有時我們無法避免制造大量的垃圾,垃圾回收器的工作也會變得非常繁重。Lua中的垃圾回收器被調(diào)節(jié)為適合平均水平的程序,因此它在多數(shù)程序中工作良好。但是,在特定的時候我們可以通過調(diào)整垃圾回收器來獲取更好的性能。通過在Lua中調(diào)用函數(shù)collectgarbage,或者在C中調(diào)用lua_gc,來控制垃圾回收器。它們的功能相同,只不過有不同的接口。在本例中我將使用Lua接口,但是這種操作通常在C中進(jìn)行更好。

collectgarbage函數(shù)提供若干種功能:它可以停止或者啟動垃圾回收器、強制進(jìn)行一次完整的垃圾回收、獲取Lua占用的總內(nèi)存,或者修改影響垃圾回收器工作節(jié)奏的兩個參數(shù)。它們在調(diào)整高內(nèi)存消耗的程序時各有用途。

“永遠(yuǎn)”停止垃圾回收器可能對于某些批處理程序很有用。這些程序創(chuàng)建若干數(shù)據(jù)結(jié)構(gòu),根據(jù)它們生產(chǎn)出一些輸出值,然后退出(例如編譯器)。對于這樣的程序,試圖回收垃圾將會是浪費時間,因為垃圾量很少,而且內(nèi)存會在程序執(zhí)行完畢后完整釋放。

對于非批處理程序,停止垃圾回收器則不是個好主意。但是,這些程序可以在某些對時間極度敏感的時期暫停垃圾回收器,以提高時間性能。如果有需要的話,這些程序可以獲取垃圾回收器的完全控制,使其始終處于停止?fàn)顟B(tài),僅在特定的時候顯式地進(jìn)行一次強制的步進(jìn)或者完整的垃圾回收。例如,很多事件驅(qū)動的平臺都提供一個選項,可以設(shè)置空閑函數(shù),在沒有消息需要處理時調(diào)用。這正是調(diào)用垃圾回收的絕好時機(在Lua 5.1中,每當(dāng)你在垃圾回收器停止的狀態(tài)下進(jìn)行強制回收,它都會恢復(fù)運轉(zhuǎn),因此,如果要保持垃圾回收器處于停止?fàn)顟B(tài),必須在強制回收后立刻調(diào)用collectgarbage("stop"))。

最后,你可能希望實施調(diào)整回收器的參數(shù)。垃圾回收器有兩個參數(shù)用于控制它的節(jié)奏:第一個,稱為暫停時間,控制回收器在完成一次回收之后和開始下次回收之前要等待多久;第二個參數(shù),稱為步進(jìn)系數(shù),控制回收器每個步進(jìn)回收多少內(nèi)容。粗略地來說,暫停時間越小、步進(jìn)系數(shù)越大,垃圾回收越快。這些參數(shù)對于程序的總體性能的影響難以預(yù)測,更快的垃圾回收器顯然會浪費更多的CPU周期,但是它會降低程序的內(nèi)存消耗總量,并可能因此減少分頁。只有謹(jǐn)慎地測試才能給你最佳的參數(shù)值。

[1] 如果標(biāo)準(zhǔn)庫提供一個用于對比兩個子串的函數(shù)可能會是一個好主意,這樣我們無需將子串解出(會創(chuàng)建新的字符串)即可檢查字符串中的特定值。

[2] 緩存化,原文memoize

您可能感興趣的文章:
  • Lua性能優(yōu)化技巧(一):前言
  • Lua性能優(yōu)化技巧(二):基本事實
  • Lua性能優(yōu)化技巧(三):關(guān)于表
  • Lua性能優(yōu)化技巧(四):關(guān)于字符串
  • Lua性能優(yōu)化技巧(六):最后的提示

標(biāo)簽:德宏 天門 天門 金昌 濰坊 臺灣 儋州 宣城

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Lua性能優(yōu)化技巧(五):削減、重用和回收》,本文關(guān)鍵詞  Lua,性能,優(yōu)化,技巧,五,削減,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Lua性能優(yōu)化技巧(五):削減、重用和回收》相關(guān)的同類信息!
  • 本頁收集關(guān)于Lua性能優(yōu)化技巧(五):削減、重用和回收的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美中文字幕一区二区三区亚洲| 日韩国产欧美在线播放| 成人午夜电影小说| 国产精品丝袜一区| 91丨porny丨蝌蚪视频| 一区二区三区在线免费观看| 欧美日韩在线播放| 久久电影网站中文字幕| 国产视频一区在线观看| jlzzjlzz欧美大全| 亚洲一区二区免费视频| 日韩天堂在线观看| 成人精品国产免费网站| 亚洲欧美色图小说| 欧美一级视频精品观看| 国产成人av电影| 一区二区三区免费在线观看| 欧美丰满少妇xxxbbb| 国内精品视频666| 国产精品国产三级国产普通话蜜臀| 色婷婷亚洲综合| 美女视频免费一区| 国产精品福利av| 67194成人在线观看| 国产成人自拍在线| 一卡二卡欧美日韩| 日韩欧美你懂的| 92精品国产成人观看免费| 日韩影院精彩在线| 国产精品久久夜| 91精品国产综合久久久久久漫画 | 国产成人综合视频| 亚洲欧美另类在线| 日韩欧美国产综合| 99久久精品久久久久久清纯| 日本中文一区二区三区| 欧美激情中文不卡| 91精品国产综合久久精品图片| 激情文学综合网| 亚洲自拍与偷拍| 国产精品久久精品日日| 精品国内二区三区| 欧美网站一区二区| 成人国产精品免费观看动漫| 日韩**一区毛片| 亚洲精品久久嫩草网站秘色| 久久精品欧美日韩精品| 91精品国产麻豆| 色999日韩国产欧美一区二区| 国产一区二区在线看| 午夜不卡av免费| 亚洲欧美日韩电影| 国产精品色一区二区三区| 欧美tk丨vk视频| 日韩一区二区在线免费观看| 欧美日韩一区三区| 91国偷自产一区二区三区观看| 国产成人丝袜美腿| 国产激情视频一区二区在线观看| 日韩不卡在线观看日韩不卡视频| 一区二区三区成人在线视频| 综合久久久久久久| 国产精品人妖ts系列视频| 久久久蜜臀国产一区二区| 欧美r级在线观看| 精品三级在线看| 欧美成人在线直播| 日韩精品在线一区二区| 欧美一级日韩一级| 7777精品伊人久久久大香线蕉 | 欧美色涩在线第一页| 色婷婷综合视频在线观看| gogogo免费视频观看亚洲一| 成人一区二区三区中文字幕| 国产99久久久久久免费看农村| 极品美女销魂一区二区三区免费| 蜜芽一区二区三区| 男女男精品视频| 国内欧美视频一区二区 | 国产精品久久久久久久午夜片| 精品成人a区在线观看| xf在线a精品一区二区视频网站| 日韩午夜在线影院| 日韩精品专区在线影院观看| 精品国产不卡一区二区三区| 精品久久久久99| 久久新电视剧免费观看| 国产亚洲欧美一级| 日韩一区欧美一区| 亚洲靠逼com| 亚洲电影视频在线| 久久精品久久综合| 国产999精品久久久久久绿帽| 成人激情免费电影网址| 91精品办公室少妇高潮对白| 欧美二区三区91| 久久综合国产精品| 国产精品久久久久婷婷二区次| 亚洲精品久久久久久国产精华液| 午夜欧美一区二区三区在线播放| 亚洲3atv精品一区二区三区| 日本欧美加勒比视频| 狠狠色丁香久久婷婷综合_中| 国产成人免费视频一区| 欧美午夜宅男影院| 2023国产精华国产精品| 一区二区中文字幕在线| 午夜电影一区二区| 成人动漫av在线| 欧美精品视频www在线观看| 欧美精品一区二区三区一线天视频| 中文字幕欧美激情一区| 亚洲成人一二三| 国产真实乱对白精彩久久| av在线一区二区| 日韩一级片在线观看| 国产精品日日摸夜夜摸av| 日韩精品一级二级 | 日韩欧美亚洲国产另类| 自拍偷拍亚洲激情| 蜜臀av国产精品久久久久| 97久久精品人人做人人爽50路| 日韩午夜精品电影| 亚洲乱码一区二区三区在线观看| 视频一区二区三区在线| 99久久久久久99| 精品国产乱码久久久久久1区2区| 亚洲免费观看高清完整版在线观看| 激情综合色综合久久综合| 91久久精品一区二区三| 国产日韩欧美制服另类| 三级在线观看一区二区| 91在线一区二区三区| 久久先锋影音av| 亚洲不卡在线观看| 色综合久久久久综合体桃花网| 久久精品夜夜夜夜久久| 亚洲成av人片在线| 99精品1区2区| 国产网红主播福利一区二区| 日本午夜精品视频在线观看| 色综合网站在线| 国产精品电影院| 成人晚上爱看视频| 国产欧美一区二区精品性| 看电视剧不卡顿的网站| 欧美一区二区三区系列电影| 亚洲综合区在线| 91小视频免费看| 国产精品久久久久久久久久免费看 | 欧美日本国产视频| 亚洲女女做受ⅹxx高潮| 不卡av电影在线播放| 国产亚洲欧美中文| 精品在线播放免费| 欧美tickle裸体挠脚心vk| 视频一区视频二区中文| 8x8x8国产精品| 三级一区在线视频先锋| 欧美日韩一区高清| 日韩综合小视频| 欧美精品丝袜久久久中文字幕| 天堂成人国产精品一区| 欧美裸体bbwbbwbbw| 亚洲成人精品一区二区| 欧美日韩电影一区| 日本欧美在线看| 精品粉嫩aⅴ一区二区三区四区| 免费人成在线不卡| 精品国产乱码久久久久久图片 | 91黄色小视频| 亚洲一区在线观看视频| 在线观看成人免费视频| 亚洲成在人线在线播放| 欧美日本一道本| 免费一级欧美片在线观看| 欧美va亚洲va| 丰满少妇在线播放bd日韩电影| 国产精品理论在线观看| 色天天综合久久久久综合片| 亚洲午夜精品久久久久久久久| 在线亚洲一区二区| 视频精品一区二区| 国产亚洲人成网站| 一本到一区二区三区| 丝袜国产日韩另类美女| 精品成人佐山爱一区二区| 顶级嫩模精品视频在线看| 亚洲欧美激情小说另类| 777久久久精品| 国产成人精品免费| 亚洲另类春色校园小说| 91精品国产品国语在线不卡| 韩国欧美一区二区| 亚洲免费大片在线观看| 欧美一级片在线| 粉嫩一区二区三区在线看| 亚洲精品一卡二卡| 精品区一区二区| 日本丶国产丶欧美色综合|