2014-04-01 57 views
5

我有兩個字符串。其中之一經常(但不總是)空着。另一個是巨大的:Lua優化與空字符串連接嗎?

a = "" 
b = "... huge string ..." 

我需要連接兩個字符串。所以,我做到以下幾點:

return a .. b 

但是,如果a是空的,這會,暫時不必要創造巨大的字符串的副本。

所以我想如下寫它:

return (a == "" and b) or (a .. b) 

這樣就解決了問題。但是,我想知道:Lua是否優化了一個涉及空字符串的串聯?也就是說,如果我們寫a .. b,Lua檢查是否有任何字符串是空的並立即返回另一個字符串?如果是這樣,我可以簡單地寫a ..b而不是更詳細的代碼。

+0

這可能是有用的:http://stackoverflow.com/questions/19138974/does-lua-optimize-the-operator – filmor

+0

@filmor:這是我自己誰問了另一個問題,這是不相關的一:另一個問題是關於將((a .. b).. c).. d')摺疊成「..(a,b,c,d)'。 *這個問題涉及其他事情。 –

+0

@Leri:我沒有看到如何檢查字節碼可以幫助我回答這個問題:在運行時字符串不是空的*,而不是在編譯時。我上面寫的代碼'a =「」'只是爲了解釋問題。在現實生活中,這將是'a = ...一些表達......'。 –

回答

6

是的,它的確如此。

在5.2的Lua代碼luaV_concat

if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { 
    if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) 
    luaG_concaterror(L, top-2, top-1); 
} 
else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ 
    (void)tostring(L, top - 2); /* result is first operand */ 
else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { 
    setobjs2s(L, top - 2, top - 1); /* result is second op. */ 
} 
else { 
    /* at least two non-empty string values; get as many as possible */ 

兩個else if部分恰好做優化字符串連接當操作數的一個是空字符串的作業。

+3

+1直接引用來源 – legends2k

+1

感謝您指引我正確的方向。我看到Lua 5.1(我的目標)[不做這個優化](http://www.lua.org/source/5.1/lvm.c.html#luaV_concat)。 LuaJIT似乎更糟(https://github.com/LuaDist/luajit/blob/master/src/lj_api.c#L704)。所以我必須自己做這個優化。 (如果我錯了,請糾正我。) –

+0

@NiccoloM。這很有趣,不知道區別。乍一看,似乎在Lua 5.1和LuaJIT源代碼中都檢查了零長度,但我沒有詳細說明,當我確定它們的功能時,我會記得更新答案。 –