北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
查看: 17054|回复: 20

给你的lua提速

[复制链接]
发表于 2017-7-1 10:01:46 | 显示全部楼层 |阅读模式
一直觉得mc自带mapper.lua计算狂慢,终于找到原因了。
下面是老外测试的结果,总结一下。
1, table.insert 比 table[n+1]=xxxx 慢7倍!!!
2,在函数a调用函数b,比函数b作为参数传递给函数a,慢10倍!!!

换了新写法,感觉好爽


Lua's performance
= Things you should know about Lua's performance =

This wiki is a result of some lua performance tests (the widget is included with ca sandbox).
[[BR]][[BR]][[BR]]


== TEST 1: localize ==
Code:
{{{
#!lua
local min = math.min
}}}
Results:
{{{
#!html

normal way: 0.719 (158%)

localized: 0.453 (100%)

}}}
Conclusion:
{{{
-> Yeah, we should localize all used funtions.
}}}

== TEST 2: localized class-methods (with only 3 accesses!) ==
Code1:
{{{
#!lua
for i=1,1000000 do
local x = class.test()
local y = class.test()
local z = class.test()
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
local test = class.test
local x = test()
local y = test()
local z = test()
end
}}}
Results:
{{{
#!html

normal way: 1.203 (102%)

localized: 1.172 (100%)

}}}
Conclusion:
{{{
-> No, it isn't faster to localize a class method IN the function call.
}}}

== TEST 3: unpack a table ==
Code1:
{{{
#!lua
for i=1,1000000 do
local x = min( a[1],a[2],a[3],a[4] )
end
}}}
Code2:
{{{
#!lua
local unpack = unpack
for i=1,1000000 do
local x = min( unpack(a) )
end
}}}
Code3:
{{{
#!lua
local function unpack4(a)
return a[1],a[2],a[3],a[4]
end
for i=1,1000000 do
local x = min( unpack4(a) )
end
}}}
Results:
{{{
#!html

with [ ]: 0.485 (100%)

unpack(): 1.093 (225%)

custom unpack4: 0.641 (131%)

}}}
Conclusion:
{{{
-> Don't use unpack() in time critical code!
}}}

== TEST 4: determine maximum and set it ('>' vs. max) ==
Code1:
{{{
#!lua
local max = math.max
for i=1,1000000 do
x = max(random(cnt),x)
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
local r = random(cnt)
if (r>x) then x = r end
end
}}}
Results:
{{{
#!html

math.max: 0.437 (156%)

'if > then': 0.282 (100%)

}}}
Conclusion:
{{{
-> Don't use math.[max|min]() in time critical code!
}}}

== TEST 5: nil checks ('if' vs. 'or') ==
Code1:
{{{
#!lua
for i=1,1000000 do
local y,x
if (random()>0.5) then y=1 end
if (y==nil) then x=1 else x=y end
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
local y
if (random()>0.5) then y=1 end
local x=y or 1
end
}}}
Results:
{{{
#!html

nil-check: 0.297 (106%)

a=x or y: 0.281 (100%)

}}}
Conclusion:
{{{
-> WOW! the or-operator is faster than a nil-check. Use it! :D
}}}

== TEST 6: 'x^2^' vs. 'x*x' ==
Code1:
{{{
#!lua
for i=1,1000000 do
local y = x^2
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
local y = x*x
end
}}}
Results:
{{{
#!html

x^2: 1.422 (110%)

x*x: 1.297 (100%)

}}}

== TEST 7: modulus operators (math.mod vs. %) ==
Code1:
{{{
#!lua
local fmod = math.fmod
for i=1,1000000 do
if (fmod(i,30)<1) then
local x = 1
end
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
if ((i%30)<1) then
local x = 1
end
end
}}}
Results:
{{{
#!html

math.mod: 0.281 (355%)

%: 0.079 (100%)

}}}
Conclusion:
{{{
-> Don't use math.fmod() for positive numbers (for negative ones % and fmod() have different results!)!
}}}

== TEST 8: functions as param for other functions ==
Code1:
{{{
#!lua
local func1 = function(a,b,func)
return func(a+b)
end

for i=1,1000000 do
local x = func1(1,2,function(a) return a*2 end)
end
}}}
Code2:
{{{
#!lua
local func1 = function(a,b,func)
return func(a+b)
end
local func2 = function(a)
return a*2
end

for i=1,1000000 do
local x = func1(1,2,func2)
end
}}}
Results:
{{{
#!html

defined in function param: 3.890 (1144%)

defined as local: 0.344 (100%)

}}}
Conclusion:
{{{
-> REALLY, LOCALIZE YOUR FUNCTIONS ALWAYS BEFORE SENDING THEM INTO ANOTHER FUNCTION!!!
i.e if you use gl.BeginEnd(), gl.CreateList(), ...!!!
}}}

== TEST 9: for-loops ==
Code1:
{{{
#!lua
for i=1,1000000 do
for j,v in pairs(a) do
x=v
end
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
for j,v in ipairs(a) do
x=v
end
end
}}}
Code3:
{{{
#!lua
for i=1,1000000 do
for i=1,100 do
x=a
end
end
}}}
Code4:
{{{
#!lua
for i=1,1000000 do
for i=1,#a do
x=a
end
end
}}}
Code5:
{{{
#!lua
for i=1,1000000 do
local length = #a
for i=1,length do
x=a
end
end
}}}
Results:
{{{
#!html

pairs: 3.078 (217%)

ipairs: 3.344 (236%)

for i=1,x do: 1.422 (100%)

for i=1,#atable do 1.422 (100%)

for i=1,atable_length do: 1.562 (110%)

}}}
Conclusion:
{{{
-> Don't use pairs() or ipairs()!
Try to save the table-size somewhere and use "for i=1,x do"!
}}}

== TEST 10: array access (with [ ]) vs. object access (with .method) ==
Code1:
{{{
#!lua
for i=1,1000000 do
x = a["foo"]
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
x = a.foo
end
}}}
Results:
{{{
#!html

atable["foo"]: 1.125 (100%)

atable.foo: 1.141 (101%)

}}}

== TEST 11: buffered table item access ==
Code1:
{{{
#!lua
for i=1,1000000 do
for n=1,100 do
a[n].x=a[n].x+1
end
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
for n=1,100 do
local y = a[n]
y.x=y.x+1
end
end
}}}
Results:
{{{
#!html

'a[n].x=a[n].x+1': 1.453 (127%)

'local y=a[n]; y.x=y.x+1': 1.140 (100%)

}}}

== TEST 12: adding table items (table.insert vs. [ ]) ==
Code1:
{{{
#!lua
local tinsert = table.insert
for i=1,1000000 do
tinsert(a,i)
end
}}}
Code2:
{{{
#!lua
for i=1,1000000 do
a=i
end
}}}
Code3:
{{{
#!lua
for i=1,1000000 do
a[#a+1]=i
end
}}}
Code4:
{{{
#!lua
local count = 1
for i=1,1000000 do
d[count]=i
count=count+1
end
}}}
Results:
{{{
#!html

table.insert: 1.250 (727%)

a: 0.172 (100%)

a[#a+1]=x: 0.453 (263%)

a[count++]=x: 0.203 (118%)

}}}
Conclusion:
{{{
-> Don't use table.insert!!!
Try to save the table-size somewhere and use "a[count+1]=x"!
}}}

北大侠客行MUD,中国最好的MUD
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-1 12:02:00 | 显示全部楼层
拆成单个字符 我居然全都看懂了!
太棒了!
合在一起 一脸蒙蔽
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-1 13:02:14 | 显示全部楼层
这是 天书吗?
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-1 14:48:38 | 显示全部楼层
这都是测试过程吧。
提高运行速度的具体方法是什么?
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-1 15:12:12 | 显示全部楼层
厉害了我的锅
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-1 19:47:22 | 显示全部楼层
table.insert和table.remove因为算法原因开销极大,而且呈指数级增长。
所以并不推荐用在大型table中,具体多大呢?超过300字节就不推荐用
个人感觉最好不要养成用它们的习惯,就当它们不存在
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-2 07:31:44 | 显示全部楼层
一脸懵逼
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-2 11:43:22 | 显示全部楼层
回复 6# creat


    table.insert 直接用 table[key]=value操作
    table.remove 直接 table[key]=nil 就可以了 ?

table.insert 和 remove 和索引直接操作的区别是啥?
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-2 23:16:49 | 显示全部楼层
回复 8# suwuji


    具体原理是什么忘记了,资料也没查到。大致意思是insert和remove是把table中的所有键值以栈的形式解包到内存(多次)后再一个栈一个栈的重新压入,所以是指数级的开销。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2017-7-3 13:56:30 | 显示全部楼层
根本看不懂,任重道远啊
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大侠客行MUD ( 京ICP备16065414号-1 )

GMT+8, 2024-11-1 09:28 AM , Processed in 0.010183 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表