×

Langue

Fermer
Atelier 801
  • Forums
  • Dev Tracker
  • Connexion
    • English Français
      Português do Brasil Español
      Türkçe Polski
      Magyar Română
      العربية Skandinavisk
      Nederlands Deutsch
      Bahasa Indonesia Русский
      中文 Filipino
      Lietuvių kalba 日本語
      Suomi עברית
      Italiano Česky
      Hrvatski Slovensky
      Български Latviešu
      Estonian
  • Langue
  • Tribus
  • /
  • The Great World Alliance
  • /
  • Zigwin's Basement
  • /
  • [Tutorial / Tips] Lua Performance
[Tutorial / Tips] Lua Performance
Zigwin
« Citoyen »
Lua Expert
1565103960000
    • Zigwin#0000
    • Profil
    • Derniers messages
    • Tribu
#1
  0

Тесты производительности

Тест 1: Локализация

Code Lua

1
local min = math.min

  — Результаты

Не локальная: 0.719 (158%)
Локальная: 0.453 (100%)

  — Вывод

Да, нам стоит использовать локальные Lua функции

Тест 2: Локальные Методы Классов

Code Lua

1
2
3
4
5
for i=1,1000000 do
local x = class.test()
local y = class.test()
local z = class.test()
end
Code Lua

1
2
3
4
5
6
for i=1,1000000 do
local test = class.test
local x = test()
local y = test()
local z = test()
end
  — Результаты

Обычный способ: 1.203 (102%)
Локальный: 1.172 (100%)

  — Вывод

Использование локальных методов классов не сильно быстрее (ВНУТРИ самой функции)

Тест 3: Unpack таблицы

Code Lua

1
2
3
for i=1,1000000 do
local x = min( a[1],a[2],a[3],a[4] )
end
Code Lua

1
2
3
4
local unpack = unpack
for i=1,1000000 do
local x = min( unpack(a) )
end
Code Lua

1
2
3
4
5
6
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
  — Результаты

используя [ ]: 0.485 (100%)
unpack(): 1.093 (225%)
unpack4: 0.641 (131%)

  — Вывод

Не используйте unpack() в критичном для времени коде!

Тест 4: Определение максимума ('>' vs. max)

Code Lua

1
2
3
4
local max = math.max
for i=1,1000000 do
x = max(random(cnt),x)
end
Code Lua

1
2
3
4
for i=1,1000000 do
local r = random(cnt)
if (r>x) then x = r end
end
  — Результаты

math.max: 0.437 (156%)
'if > then': 0.282 (100%)

  — Вывод

Не используйте math.[max|min]() в критичном для времени коде!

Тест 5: Nil проверка ('if' vs. 'or')

Code Lua

1
2
3
4
5
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
Code Lua

1
2
3
4
5
for i=1,1000000 do
local y
if (random()>0.5) then y=1 end
local x=y or 1
end
  — Результаты

nil проверка: 0.297 (106%)
a=x or y: 0.281 (100%)

  — Вывод

or быстрее nil проверки. Используй его!

Тест 6: 'x^2' vs. 'x*x'

Code Lua

1
2
3
for i=1,1000000 do
local y = x^2
end
Code Lua

1
2
3
for i=1,1000000 do
local y = x*x
end
  — Результаты

x^2: 1.422 (110%)
x*x: 1.297 (100%)

  — Вывод

Второй вариант немного быстрее

Тест 7: Модульные операторы (math.mod vs. %)

Code Lua

1
2
3
4
5
6
local fmod = math.fmod
for i=1,1000000 do
if (fmod(i,30)<1) then
local x = 1
end
end
Code Lua

1
2
3
4
5
for i=1,1000000 do
if ((i%30)<1) then
local x = 1
end
end
  — Результаты

math.mod: 0.281 (355%)
%: 0.079 (100%)

  — Вывод

Не используйте math.fmod() для положительных чисел (для негативных % и fmod() имеют различные результаты!)

Тест 8: Функции как параметр для других функций

Code Lua

1
2
3
4
5
6
7
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
Code Lua

1
2
3
4
5
6
7
8
9
10
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
  — Результаты

определена как параметр функций: 3.890 (1144%)
определена как локальная: 0.344 (100%)

  — Вывод

Локализуйте функции перед тем как использовать их в других функциях!!!

Тест 9: for цикл

Code Lua

1
2
3
4
5
for i=1,1000000 do
for j,v in pairs(a) do
x=v
end
end
Code Lua

1
2
3
4
5
for i=1,1000000 do
for j,v in ipairs(a) do
x=v
end
end
Code Lua

1
2
3
4
5
for i=1,1000000 do
for i=1,100 do
x=a[i]
end
end
Code Lua

1
2
3
4
5
for i=1,1000000 do
for i=1,#a do
x=a[i]
end
end
Code Lua

1
2
3
4
5
6
for i=1,1000000 do
local length = #a
for i=1,length do
x=a[i]
end
end
  — Результаты

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%)

  — Вывод

Не используйте pairs() или ipairs() ! Пытайтесь сохранить размер таблицы где-то и использовать for i=1,x do!

Тест 10: Доступ к таблице

Code Lua

1
2
3
for i=1,1000000 do
x = a["foo"]
end
Code Lua

1
2
3
for i=1,1000000 do
x = a.foo
end
  — Результаты

atable["foo"]: 1.125 (100%)
atable.foo: 1.141 (101%)

  — Вывод

Нет разницы

Тест 11: Доступ к данным буферизированной таблицы

Code Lua

1
2
3
4
5
for i=1,1000000 do
for n=1,100 do
a[n].x=a[n].x+1
end
end
Code Lua

1
2
3
4
5
6
for i=1,1000000 do
for n=1,100 do
local y = a[n]
y.x=y.x+1
end
end
  — Результаты

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

  — Вывод

Буферизация может ускорить доступ к данным таблицы

Тест 12: Добавление данных в таблицу

Code Lua

1
2
3
4
local tinsert = table.insert
for i=1,1000000 do
tinsert(a,i)
end
Code Lua

1
2
3
for i=1,1000000 do
a[i]=i
end
Code Lua

1
2
3
for i=1,1000000 do
a[#a+1]=i
end
Code Lua

1
2
3
4
5
local count = 1
for i=1,1000000 do
d[count]=i
count=count+1
end
  — Результаты

table.insert: 1.250 (727%)
a i: 0.172 (100%)
a[#a+1]=x: 0.453 (263%)
a[count++]=x: 0.203 (118%)

  — Вывод

Не используйте table.insert!!! Попробуйте сохранить размер таблицы и использовать a[count+1]=x!

Нет перевода Тест 12+: Добавление данных в таблицу (mytable ={} vs. mytable={...})

When you write {true, true, true} , Lua knows beforehand that the table will need three slots in its array part, so Lua creates the table with that size. Similarly, if you write {x = 1, y = 2, z = 3}, Lua will create a table with four slots in its hash part.

As an example, the next loop runs in 2.0 seconds:
Code Lua

1
2
3
4
for i = 1, 1000000 do
local a = {}
a[1] = 1; a[2] = 2; a[3] = 3
end
If we create the tables with the right size, we reduce the run t ime to 0.7 seconds:
Code Lua

1
2
3
4
for i = 1, 1000000 do
local a = {true, true, true}
a[1] = 1; a[2] = 2; a[3] = 3
end
If you write something like {[1] = true, [2] = true, [3] = true}, however, Lua is not smart enough to detect that the given expressions (literal numbers, in this case) describe array indices, so it creates a table with four slots in its hash part, wasting memory and CPU time


Тест 13: Статическая инициализация таблиц vs локальная


Code Lua

1
2
3
4
local CachedTable= {"abc","def","ghk"}
for i=1 , 10000000, 1 do
t[i] = CachedTable
end
Code Lua

1
2
3
for i=1 , 10000000, 1 do
t[i] = {"abc","def","ghk"}
end

  — Результаты

статическая инициализация: 500 %
локальная инициализация: 100 %

  — Вывод

Lua плох в определении статических инициализаторов, не используйте их, используйте локальные инициализации.

Данная статься является переводом другой статьи

Dernière modification le 1565106240000
  • Tribus
  • /
  • The Great World Alliance
  • /
  • Zigwin's Basement
  • /
  • [Tutorial / Tips] Lua Performance
© Atelier801 2018

Equipe Conditions Générales d'Utilisation Politique de Confidentialité Contact

Version 1.27