1. 程式人生 > >Lua大量字串拼接方式效率對比及原因分析

Lua大量字串拼接方式效率對比及原因分析

零、字串拼接除了下方所述的方法還有string.format(...),但是這個不適合拼接大量字串,故不說明。
一、大量字串拼接方式
1. 使用運算子..
2. 使用table.concat (table [, sep [, start [, end]]])函式

二、實驗
1. 程式碼
function operatorConcat(str,count)
    local result = ""
    for i=1,count do
        result = result .. str
    end
    return result
end

function tableConcat(str,count)
    local tbl = {}
    for i=1,count do
        table.insert( tbl,str)
    end
    return table.concat(tbl)
end


local str = "a"
local count = 100000

local start_time = os.clock()
operatorConcat(str,count)
print("operatorConcatTime:" .. os.clock() - start_time)

start_time = os.clock()
tableConcat(str,count)
print("tableConcatTime:" .. os.clock() - start_time)
2. 結果
    從圖中看到,將100000個str="a"拼接成新的字串,運算子..的時間是0.55919s,而table.concat()函式時間為0.023939s,差距20+倍。

三、原因分析
1. 使用運算子..
    每次拼接都需要申請新的空間,舊的result對應的空間會在某時刻被Lua的垃圾回收期GC,且隨著result不斷增長,越往後會開闢更多新的空間,並進行拷貝操作,產生更多需要被GC的空間,所以效能降低。
2. 使用table.concat (table [, sep [, start [, end]]])函式
    table.concat 底層拼接字串的方式也是使用運算子.. ,但是其使用演算法減少了使用運算子..的次數,減少了GC,從而提高效率。主要思路:採用二分思想,用棧儲存字串,新入棧的字串與下方的字串比較長度,大於則使用運算子..拼接成新字串,並移除棧頂的字串,不斷向下直至遇到長度更大的字串或者棧底,這樣保持最大的字串位於棧底,棧呈現金字塔的形狀,最終在使用運算子..將棧中的字串拼接成最終的字串。

四、參考連結
http://www.lua.org/pil/11.6.html
http://www.jb51.net/article/55124.htm