校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁(yè) > 知識(shí)庫(kù) > Lua性能優(yōu)化技巧(三):關(guān)于表

Lua性能優(yōu)化技巧(三):關(guān)于表

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

一般情況下,你不需要知道Lua實(shí)現(xiàn)表的細(xì)節(jié),就可以使用它。實(shí)際上,Lua花了很多功夫來(lái)隱藏內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)。但是,實(shí)現(xiàn)細(xì)節(jié)揭示了表操作的性能開銷情況。因此,要優(yōu)化使用表的程序(這里特指Lua程序),了解一些表的實(shí)現(xiàn)細(xì)節(jié)是很有好處的。

Lua的表的實(shí)現(xiàn)使用了一些很聰明的算法。每個(gè)Lua表的內(nèi)部包含兩個(gè)部分:數(shù)組部分和哈希部分。數(shù)組部分以從1到一個(gè)特定的n之間的整數(shù)作為鍵來(lái)保存元素(我們稍后即將討論這個(gè)n是如何計(jì)算出來(lái)的)。所有其他元素(包括在上述范圍之外的整數(shù)鍵)都被存放在哈希部分里。

正如其名,哈希部分使用哈希算法來(lái)保存和查找鍵。它使用被稱為開放地址表的實(shí)現(xiàn)方式,意思是說(shuō)所有的元素都保存在哈希數(shù)組中。用一個(gè)哈希函數(shù)來(lái)獲取一個(gè)鍵對(duì)應(yīng)的索引;如果存在沖突的話(意即,如果兩個(gè)鍵產(chǎn)生了同一個(gè)哈希值),這些鍵將會(huì)被放入一個(gè)鏈表,其中每個(gè)元素對(duì)應(yīng)一個(gè)數(shù)組項(xiàng)。當(dāng)Lua需要向表中添加一個(gè)新的鍵,但哈希數(shù)組已滿時(shí),Lua將會(huì)重新哈希。重新哈希的第一步是決定新的數(shù)組部分和哈希部分的大小。因此,Lua遍歷所有的元素,計(jì)數(shù)并對(duì)其進(jìn)行歸類,然后為數(shù)組部分選擇一個(gè)大小,這個(gè)大小相當(dāng)于能使數(shù)組部分超過一半的空間都被填滿的2的最大的冪;然后為哈希部分選擇一個(gè)大小,相當(dāng)于正好能容納哈希部分所有元素的2的最小的冪。

當(dāng)Lua創(chuàng)建空表時(shí),兩個(gè)部分的大小都是0。因此,沒有為其分配數(shù)組。讓我們看一看當(dāng)執(zhí)行下面的代碼時(shí)會(huì)發(fā)生什么:

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

local a = {}
for i = 1, 3 do
    a[i] = true
end

這段代碼始于創(chuàng)建一個(gè)空表。在循環(huán)的第一次迭代中,賦值語(yǔ)句
復(fù)制代碼 代碼如下:

a[1] = true

觸發(fā)了一次重新哈希;Lua將數(shù)組部分的大小設(shè)為1,哈希部分依然為空;第二次迭代時(shí)
復(fù)制代碼 代碼如下:

a[2] = true

觸發(fā)了另一次重新哈希,將數(shù)組部分?jǐn)U大為2.最終,第三次迭代又觸發(fā)了一次重新哈希,將數(shù)組部分的大小擴(kuò)大為4。

類似下面的代碼

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

a = {}
a.x = 1; a.y = 2; a.z = 3

做的事情類似,只不過增加的是哈希部分的大小。

對(duì)于大的表來(lái)說(shuō),初期的幾次重新哈希的開銷被分?jǐn)偟秸麄€(gè)表的創(chuàng)建過程中,一個(gè)包含三個(gè)元素的表需要三次重新哈希,而一個(gè)有一百萬(wàn)個(gè)元素的表也只需要二十次。但是當(dāng)創(chuàng)建幾千個(gè)小表的時(shí)候,重新哈希帶來(lái)的性能影響就會(huì)非常顯著。

舊版的Lua在創(chuàng)建空表時(shí)會(huì)預(yù)選分配大小(4,如果我沒有記錯(cuò)的話),以防止在初始化小表時(shí)產(chǎn)生的這些開銷。但是這樣的實(shí)現(xiàn)方式會(huì)浪費(fèi)內(nèi)存。例如,如果你要?jiǎng)?chuàng)建數(shù)百萬(wàn)個(gè)點(diǎn)(表現(xiàn)為包含兩個(gè)元素的表),每個(gè)都使用了兩倍于實(shí)際所需的內(nèi)存,就會(huì)付出高昂的代價(jià)。這也是為什么Lua不再為新表預(yù)分配數(shù)組。

如果你使用C編程,可以通過Lua的API函數(shù)lua_createtable來(lái)避免重新哈希;除lua_State之外,它還接受兩個(gè)參數(shù):數(shù)組部分的初始大小和哈希部分的初始大小[1]。只要指定適當(dāng)?shù)闹担涂梢员苊獬跏蓟瘯r(shí)的重新哈希。需要警惕的是,Lua只會(huì)在重新哈希時(shí)收縮表的大小,因此如果在初始化時(shí)指定了過大的值,Lua可能永遠(yuǎn)不會(huì)糾正你浪費(fèi)的內(nèi)存空間。

當(dāng)使用Lua編程時(shí),你可能可以使用構(gòu)造式來(lái)避免初始化時(shí)的重新哈希。當(dāng)你寫下

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

{true, true, true}

時(shí),Lua知道這個(gè)表的數(shù)組部分將會(huì)有三個(gè)元素,因此會(huì)創(chuàng)建相應(yīng)大小的數(shù)組。類似的,如果你寫下
復(fù)制代碼 代碼如下:

{x = 1, y = 2, z = 3}

Lua也會(huì)為哈希部分創(chuàng)建一個(gè)大小為4的數(shù)組。例如,執(zhí)行下面的代碼需要2.0秒:
復(fù)制代碼 代碼如下:

for i = 1, 1000000 do
    local a = {}
    a[1] = 1; a[2] = 2; a[3] = 3
end

如果在創(chuàng)建表時(shí)給定正確的大小,執(zhí)行時(shí)間可以縮減到0.7秒:
復(fù)制代碼 代碼如下:

for i = 1, 1000000 do
    local a = {true, true, true}
    a[1] = 1; a[2] = 2; a[3] = 3
end

但是,如果你寫類似于
復(fù)制代碼 代碼如下:

{[1] = true, [2] = true, [3] = true}

的代碼,Lua還不夠聰明,無(wú)法識(shí)別表達(dá)式(在本例中是數(shù)值字面量)指定的數(shù)組索引,因此它會(huì)為哈希部分創(chuàng)建一個(gè)大小為4的數(shù)組,浪費(fèi)內(nèi)存和CPU時(shí)間。

兩個(gè)部分的大小只會(huì)在Lua重新哈希時(shí)重新計(jì)算,重新哈希則只會(huì)發(fā)生在表完全填滿后,Lua需要插入新的元素之時(shí)。因此,如果你遍歷一個(gè)表并清除其所有項(xiàng)(也就是全部設(shè)為nil),表的大小不會(huì)縮小。但是此時(shí),如果你需要插入新的元素,表的大小將會(huì)被調(diào)整。多數(shù)情況下這都不會(huì)成為問題,但是,不要指望能通過清除表項(xiàng)來(lái)回收內(nèi)存:最好是直接把表自身清除掉。

一個(gè)可以強(qiáng)制重新哈希的猥瑣方法是向表中插入足夠多的nil。例如:

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

a = {}
lim = 10000000
for i = 1, lim do a[i] = i end              -- 創(chuàng)建一個(gè)巨表
print(collectgarbage("count"))              --> 196626
for i = 1, lim do a[i] = nil end            -- 清除所有元素
print(collectgarbage("count"))              --> 196626
for i = lim + 1, 2 * lim do a[i] = nil end -- 創(chuàng)建一堆nil元素
print(collectgarbage("count"))              --> 17

除非是在特殊情況下,我不推薦使用這個(gè)伎倆:它很慢,并且沒有簡(jiǎn)單的方法能知道要插入多少nil才夠。

你可能會(huì)好奇Lua為什么不會(huì)在清除表項(xiàng)時(shí)收縮表。首先是為了避免測(cè)試寫入表中的內(nèi)容。如果在賦值時(shí)檢查值是否為nil,將會(huì)拖慢所有的賦值操作。第二,也是最重要的,允許在遍歷表時(shí)將表項(xiàng)賦值為nil。例如下面的循環(huán):

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

for k, v in pairs(t) do
    if some_property(v) then
        t[k] = nil – 清除元素
    end
end

如果Lua在每次nil賦值后重新哈希這張表,循環(huán)就會(huì)被破壞。

如果你想要清除一個(gè)表中的所有元素,只需要簡(jiǎn)單地遍歷它:

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

for k in pairs(t) do
    t[k] = nil
end

一個(gè)“聰明”的替代解決方案:
復(fù)制代碼 代碼如下:

while true do
    local k = next(t)
    if not k then break end
    t[k] = nil
end

但是,對(duì)于大表來(lái)說(shuō),這個(gè)循環(huán)將會(huì)非常慢。調(diào)用函數(shù)next時(shí),如果沒有給定前一個(gè)鍵,將會(huì)返回表的第一個(gè)元素(以某種隨機(jī)的順序)。在此例中,next將會(huì)遍歷這個(gè)表,從開始尋找一個(gè)非nil元素。由于循環(huán)總是將找到的第一個(gè)元素置為nil,因此next函數(shù)將會(huì)花費(fèi)越來(lái)越長(zhǎng)的時(shí)間來(lái)尋找第一個(gè)非nil元素。這樣的結(jié)果是,這個(gè)“聰明”的循環(huán)需要20秒來(lái)清除一個(gè)有100,000個(gè)元素的表,而使用pairs實(shí)現(xiàn)的循環(huán)則只需要0.04秒。

[1] 盡管重新哈希算法始終設(shè)置數(shù)組的大小為2的冪,數(shù)組的大小依然可以為任何自然數(shù)值。而哈希的大小必須為2的冪,所以第二個(gè)參數(shù)總是會(huì)被圓整為不小于原值的最小的2的冪。

您可能感興趣的文章:
  • Lua性能優(yōu)化技巧(一):前言
  • Lua性能優(yōu)化技巧(二):基本事實(shí)
  • Lua性能優(yōu)化技巧(四):關(guān)于字符串
  • Lua性能優(yōu)化技巧(五):削減、重用和回收
  • Lua性能優(yōu)化技巧(六):最后的提示

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

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Lua性能優(yōu)化技巧(三):關(guān)于表》,本文關(guān)鍵詞  Lua,性能,優(yōu)化,技巧,三,關(guān)于,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Lua性能優(yōu)化技巧(三):關(guān)于表》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Lua性能優(yōu)化技巧(三):關(guān)于表的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    国产专区综合网| 国产乱子伦视频一区二区三区 | 国产精品1区2区3区在线观看| 亚洲欧洲日韩av| 9191精品国产综合久久久久久| 国产成人免费视频一区| 日精品一区二区三区| 国产精品久久久久久久久图文区| 欧美一区二区三区在线| 色综合久久中文字幕综合网| 国产一区二区精品在线观看| 日韩av高清在线观看| 亚洲一区二区视频在线| 国产精品福利一区| 久久久天堂av| 精品va天堂亚洲国产| 欧美猛男超大videosgay| av一区二区三区黑人| 国产精一品亚洲二区在线视频| 日本在线不卡一区| 亚洲成人一区二区在线观看| 中文字幕人成不卡一区| 国产日本欧美一区二区| 精品成人一区二区三区| 日韩欧美aaaaaa| 欧美一级免费观看| 777午夜精品免费视频| 欧美性高清videossexo| 在线观看日韩精品| 色婷婷香蕉在线一区二区| 成人久久18免费网站麻豆| 国产成人在线影院| 国产成人av电影在线观看| 久久99精品久久久久久动态图| 午夜电影网亚洲视频| 亚洲一区二区欧美| 香蕉久久一区二区不卡无毒影院| 亚洲第四色夜色| 婷婷成人综合网| 日本美女一区二区| 三级久久三级久久| 免费在线观看一区二区三区| 午夜不卡av免费| 美女诱惑一区二区| 久久福利资源站| 91色porny蝌蚪| 色综合色综合色综合色综合色综合| 99视频精品全部免费在线| 99久久精品99国产精品| 在线视频欧美精品| 欧美一区二区福利视频| 欧美成人一区二区三区在线观看 | av在线综合网| 在线视频国内一区二区| 欧美三级三级三级| 欧美va日韩va| 国产精品久久久久久久第一福利| 中文字幕在线一区免费| 亚洲一区二区视频在线| 美女爽到高潮91| 国产传媒欧美日韩成人| 91天堂素人约啪| 4438x成人网最大色成网站| 26uuu亚洲婷婷狠狠天堂| 国产精品久久久久久久久果冻传媒 | 黑人精品欧美一区二区蜜桃| 国产成a人无v码亚洲福利| 色av综合在线| 日韩一区二区三区在线视频| 日本一区二区三区电影| 亚洲色图制服诱惑| 男人的天堂久久精品| 成人综合婷婷国产精品久久| 国产亚洲精品中文字幕| 亚洲视频在线一区二区| 亚洲va欧美va人人爽午夜| 麻豆91精品91久久久的内涵| 成人美女视频在线观看| 欧美日韩精品三区| 欧美激情中文不卡| 午夜免费久久看| 成人一区二区在线观看| 宅男在线国产精品| 国产精品免费视频观看| 日韩电影一区二区三区四区| 国产麻豆精品久久一二三| 欧美三级视频在线播放| 国产欧美日韩精品a在线观看| 亚洲一二三四在线观看| 国产成人免费高清| 91精品国产综合久久福利| 国产精品电影一区二区| 老司机午夜精品99久久| 欧美在线影院一区二区| 国产亚洲女人久久久久毛片| 亚洲成年人影院| 99re这里只有精品6| 亚洲精品一区二区三区福利 | 欧美日本一区二区| 国产精品五月天| 久久国产乱子精品免费女| 日本精品视频一区二区三区| 国产偷v国产偷v亚洲高清| 免费成人你懂的| 欧美亚洲精品一区| 中文字幕日韩精品一区| 国产成人综合亚洲网站| 精品国产自在久精品国产| 亚洲bdsm女犯bdsm网站| 91香蕉视频mp4| 国产拍揄自揄精品视频麻豆| 久久国产精品色婷婷| 56国语精品自产拍在线观看| 一区二区三区四区av| av成人动漫在线观看| 欧美国产欧美综合| 国产寡妇亲子伦一区二区| 欧美tickling网站挠脚心| 日本中文字幕一区二区有限公司| 欧美视频精品在线观看| 亚洲色图色小说| 91女神在线视频| 亚洲视频一二区| 91一区二区三区在线观看| 国产精品电影一区二区| 丰满亚洲少妇av| 国产精品久久久久久福利一牛影视 | 国产精品五月天| 风流少妇一区二区| 国产视频不卡一区| 成人免费高清在线| 国产精品国产三级国产aⅴ原创| 国产99一区视频免费 | 亚洲精品国产一区二区三区四区在线| 国产激情视频一区二区三区欧美 | 不卡一卡二卡三乱码免费网站 | 热久久一区二区| 欧美精品在线观看播放| 亚洲成a人片在线不卡一二三区 | 精品毛片乱码1区2区3区| 久久精品国产77777蜜臀| 欧美成人精品3d动漫h| 精品一区二区三区在线播放视频| 欧美xxxx老人做受| 国产精品一区免费视频| 日本一区二区三区国色天香| 99久久久精品免费观看国产蜜| 亚洲欧洲av色图| 欧美日韩一区二区欧美激情| 婷婷六月综合亚洲| 欧美变态凌虐bdsm| 国产成人99久久亚洲综合精品| 中文字幕亚洲区| 欧美日韩精品一区二区三区 | 日韩欧美国产不卡| 国产成人一区在线| 国产在线精品一区二区三区不卡| 精品少妇一区二区三区在线视频| 国产成人午夜精品影院观看视频 | 久久av老司机精品网站导航| 久久亚洲捆绑美女| 99国产欧美另类久久久精品| 一区二区三区欧美久久| 制服丝袜国产精品| 国产精品88888| 日韩码欧中文字| 777a∨成人精品桃花网| 国产激情91久久精品导航| 亚洲蜜桃精久久久久久久| 欧美精品 国产精品| 国产精品资源在线观看| 亚洲美女偷拍久久| 欧美一级理论片| 99麻豆久久久国产精品免费 | 日韩一区二区电影在线| 国产黑丝在线一区二区三区| 一区二区三区欧美亚洲| 精品91自产拍在线观看一区| 91小宝寻花一区二区三区| 日本sm残虐另类| 国产精品美女久久久久av爽李琼| 欧美性xxxxxxxx| 国产69精品久久久久777| 亚洲成人在线免费| 国产精品传媒视频| 精品国产乱子伦一区| 欧美性猛片aaaaaaa做受| 国产99久久久国产精品| 日韩av在线播放中文字幕| 国产精品国产三级国产普通话99| 日韩一卡二卡三卡四卡| av在线综合网| 国产美女视频一区| 天堂久久久久va久久久久| 国产欧美日韩综合精品一区二区 | 久久久www免费人成精品| 91高清视频在线| 国产99精品视频| 免费在线一区观看| 亚洲一二三四久久|