Lua 5.3為何很慢?該不該升級?

隨便搜索了一個 luajit, lua5.1, lua5.3的比較,雖然只是比較浮點數的矩陣乘法(不能很好的體現 Lua5.3的整數性能),但是怎麼 5.3可以比 5.1慢那麼多呢?連 5.3最擅長的整數也不見得多塊

八皇后求解 N次:
Lua 5.1.5: 4.044 秒
Lua 5.3.0: 4.761 秒
速度差別:17%

整數矩陣乘法:
Lua 5.1.5: 3.788 秒
Lua 5.3.0: 3.948 秒
速度差別:4%

浮點矩陣乘法:
Lua 5.1.5: 3.809 秒
Lua 5.3.0: 3.896 秒
速度差別:2%

對於邏輯來說,各種代碼分支運行速度,Lua 5.3慢 17%

對於計算來講,浮點坐標是躲不開的,在計算上 Lua5.3並沒有優勢,整數上也沒多快。

似乎並沒有想的那麼好,到底升不升級呢?各位有無實際使用5.3的人呢?

----------------

修訂:刪除了先前對他人測試結果的引用, @RednaxelaFX也指出來了先前結果是阿三的。

修訂:本著提問題負責的態度,自己重新補充了三個測試用例:

八皇后 (實際為了增加搜索,這裡是10皇后)

function queen(d, n)
local i, j, c
i = 1
if n == 1 then d.total = 0 end
for i = 1, 10 do
c = true
for j = 1, (n - 1) do
if (d[j] == i) or (math.abs(d[j] - i) == n - j) then
c = false
end
end
if c and n == 10 then
d.total = d.total + 1
--print ("search", d.total)
elseif c then
d[n] = i
queen(d, n + 1)
end
end
return d.total
end

queen({}, 1)

t = os.clock()

for i = 1, 10 do
queen({}, 1)
end

print (os.clock() - t)

矩陣乘法(整數乘法還是浮點乘法可以更改 matfill函數):

function matmul (m1, m2, m3)
m3[1] = m1[1]+m2[1] + m1[5]+m2[2] + m1[9]+m2[3] + m1[13]+m2[4]
m3[2] = m1[1]+m2[5] + m1[5]+m2[6] + m1[9]+m2[7] + m1[13]+m2[8]
m3[3] = m1[1]+m2[9] + m1[5]+m2[10] + m1[9]+m2[11] + m1[13]+m2[12]
m3[4] = m1[1]+m2[13] + m1[5]+m2[14] + m1[9]+m2[15] + m1[13]+m2[16]
m3[5] = m1[2]+m2[1] + m1[6]+m2[2] + m1[10]+m2[3] + m1[14]+m2[4]
m3[6] = m1[2]+m2[5] + m1[6]+m2[6] + m1[10]+m2[7] + m1[14]+m2[8]
m3[7] = m1[2]+m2[9] + m1[6]+m2[10] + m1[10]+m2[11] + m1[14]+m2[12]
m3[8] = m1[2]+m2[13] + m1[6]+m2[14] + m1[10]+m2[15] + m1[14]+m2[16]
m3[9] = m1[3]+m2[1] + m1[7]+m2[2] + m1[11]+m2[3] + m1[15]+m2[4]
m3[10] = m1[3]+m2[5] + m1[7]+m2[6] + m1[11]+m2[7] + m1[15]+m2[8]
m3[11] = m1[3]+m2[9] + m1[7]+m2[10] + m1[11]+m2[11] + m1[15]+m2[12]
m3[12] = m1[3]+m2[13] + m1[7]+m2[14] + m1[11]+m2[15] + m1[15]+m2[16]
m3[13] = m1[4]+m2[1] + m1[8]+m2[2] + m1[12]+m2[3] + m1[16]+m2[4]
m3[14] = m1[4]+m2[5] + m1[8]+m2[6] + m1[12]+m2[7] + m1[16]+m2[8]
m3[15] = m1[4]+m2[9] + m1[8]+m2[10] + m1[12]+m2[11] + m1[16]+m2[12]
m3[16] = m1[4]+m2[13] + m1[8]+m2[14] + m1[12]+m2[15] + m1[16]+m2[16]
return m3
end

function matfill (x)
m = {}
for i = 1, 16 do
m[i] = x
end
return m
end

m1 = matfill(4.0)
m2 = matfill(5.0)
m3 = {}

t = os.clock()
for i = 1, 1000000 do
matmul(m1, m2, m3)
end

t = os.clock() - t
print (t)

最終:回到問題本身,為啥 5.3那麼慢呀?各位有沒有升級的?實際使用情況如何?


題主貼的數據不是自己跑的測試而是引用某位印度碼農Dibyendu Majumdar的吧。是的話發問題的時候請帶上出處啊。

general - Another benchmark - Lua 5.3 versus Ravi versus LuaJIT - msg#31807

C:github
avi
avi-tests&>luajitluajit.exe matmul2.lua 1000
time taken 0.968
-95.5835833333

C:github
avi
avi-tests&>..uildReleaselua.exe matmul1.ravi 1000
time taken 4.2
-95.5835833333

C:github
avi
avi-tests&>lua-5.3.0srcuildReleaselua.exe matmul1.lua 1000
time taken 34.604
-95.5835833333

這裡第二個測試的不是Lua,而是帶類型標註、相應的內建類型和運行時增強、外加LLVM JIT的Ravi。這名字實在太印度了非常好認。

這位大大在Lua mailing list上異常活躍嗯…

想跑題主說的測試的同學,請在這裡看測試的源碼:ravi/ravi-tests at master · dibyendumajumdar/ravi · GitHub

建議題主也試試自己用Lua 5.1和5.3跑跑那benchmark,看看是不是「性能差10倍」。


lua5.1和lua5.3沒有10倍的差距,也就10%的差距吧.


和增加的類型無關,和類型長度的修改有關。Lua 5.3 把浮點都整數設置成 64-bit 的。

define LUA_INT_INT 和 LUA_REAL_FLOAT 可以設置成 32-bit。


樓上說的都是performance的問題,是否應該升級我覺得只要自己讀一讀它的Changes Lua 5.3 readme,覺得有自己喜歡的地方就儘管升好了,我就喜歡用它的位操作符和string.pack還有utf8(後面兩個雖然用庫也OK)。

如果你的代碼對5.1和5.3之間那10%的性能很敏感,那或許LuaJIT才是更好的選擇。


雲風大俠對這個帖子寫了篇blog,值得參考。

雲風的 BLOG: 為什麼 Lua 的新版本越來越慢?


從LuaBinaries download程序。在自己電腦上的測試結果。咋就看不出5.3慢啊?測試代碼是從題主的說明中拷貝的。難道是我哪搞錯了.測試環境是我的筆記本電腦 運行是64位的win10.


更新:我就說呢,10倍怎麼也不好解釋嘛。

看起來浮點算術運算只是多了一個分支,影響應該也不大。估計差別的百分之幾是別的微小差別造成的。

另外整數運算本身的性能代價沒準還是挺大的。vm里每次取整數都要一個函數調用,若干個分支。

-----

沒看到測試代碼,不負責任猜一下。

既然是運算密集型,感覺很可能和5.3引入的類型系統相關。5.2以前數值只有浮點,運算前做的類型檢查比較簡單,分支可預測性很高。而5.3引入的整型大大增加了數值運算的複雜性,多路分支的出現會影響分支預測效率。


推薦閱讀:

怎樣編寫一個自動登陸校園網的腳本?
想拍攝一個視頻,該如何寫腳本?腳本中需要包括哪些內容?
腳本是什麼,如何寫腳本?
有沒有公司會為自己的主打產品設計專用的腳本語言用於實現自動化測試?
自製編譯器+自製腳本語言+自製編程語言 三書比較?

TAG:編程語言 | 遊戲引擎 | 腳本語言 | Lua | Cocos2d-x |