Я люблю Lua. I love Lua.

Вопросы производительности — 3

Posted in Uncategorized by ilovelua on 17 сентября, 2012

Рассмотрим скорость доступа модуля к локальной переменной и к полю, объявленному внутри модуля. Код модуля:

module('TestModule', package.seeall)

local localTable = {}
testTable = {}

-- добавляем в модуль полей, чтобы поиск осуществлялся не в совсем пустой таблице
for i = 1, 100 do
    _M['testTable' .. i] = i
end

function getTestTable()
    return testTable
end

function getLocalTable()
    return localTable
end

Код теста:

local TestModule = require('TestModule')

local count = 1000000

function test()
    local t = os.clock ()

    for i = 1, count do
        TestModule.getTestTable()[i] = i
    end

    local t1 = os.clock () - t

    t = os.clock ()

    for i = 1, count do
        TestModule.getLocalTable()[i] = i
    end

    local t2 = os.clock () - t

    return t1, t2
end

local percents = {}

for i = 1, 100 do
    local t1, t2 = test()
    local delta = string.format('%.6f', t1 - t2)
    local p = string.format('%.6f', ((t1 - t2) / t1) * 100)

    print(i, 'delta:', delta, '%', p)

    table.insert(percents, p)
end

local totalPercents = 0

for i, percent in ipairs(percents) do
    totalPercents = totalPercents + percent
end

print('average percents is:', totalPercents / #percents)

Результаты:

1 delta: 0.028000 % 9.395973
2 delta: 0.015000 % 5.514706
3 delta: 0.013000 % 4.779412
4 delta: 0.015000 % 5.494505
5 delta: 0.011000 % 4.044118
6 delta: 0.015000 % 5.494505
7 delta: 0.014000 % 5.128205
8 delta: 0.015000 % 5.474453
9 delta: 0.014000 % 5.147059
10 delta: 0.014000 % 5.147059
11 delta: 0.011000 % 4.044118
12 delta: 0.014000 % 5.147059
13 delta: 0.012000 % 4.411765
14 delta: 0.011000 % 4.074074
15 delta: 0.012000 % 4.411765
16 delta: 0.015000 % 5.494505
17 delta: 0.014000 % 5.128205
18 delta: 0.013000 % 4.779412
19 delta: 0.013000 % 4.761905
20 delta: 0.013000 % 4.797048
21 delta: 0.013000 % 4.779412
22 delta: 0.015000 % 5.494505
23 delta: 0.015000 % 5.494505
24 delta: 0.013000 % 4.779412
25 delta: 0.011000 % 4.059041
26 delta: 0.013000 % 4.779412
27 delta: 0.013000 % 4.761905
28 delta: 0.013000 % 4.779412
29 delta: 0.013000 % 4.797048
30 delta: 0.014000 % 5.147059
31 delta: 0.015000 % 5.494505
32 delta: 0.014000 % 5.147059
33 delta: 0.014000 % 5.128205
34 delta: 0.014000 % 5.147059
35 delta: 0.014000 % 5.147059
36 delta: 0.014000 % 5.147059
37 delta: 0.015000 % 5.494505
38 delta: 0.015000 % 5.494505
39 delta: 0.014000 % 5.147059
40 delta: 0.014000 % 5.147059
41 delta: 0.014000 % 5.128205
42 delta: 0.016000 % 5.860806
43 delta: 0.014000 % 5.147059
44 delta: 0.014000 % 5.147059
45 delta: 0.014000 % 5.147059
46 delta: 0.012000 % 4.411765
47 delta: 0.013000 % 4.779412
48 delta: 0.015000 % 5.514706
49 delta: 0.013000 % 4.779412
50 delta: 0.013000 % 4.779412
51 delta: 0.014000 % 5.128205
52 delta: 0.012000 % 4.411765
53 delta: 0.015000 % 5.494505
54 delta: 0.016000 % 5.860806
55 delta: 0.015000 % 5.494505
56 delta: 0.014000 % 5.147059
57 delta: 0.015000 % 5.514706
58 delta: 0.014000 % 5.147059
59 delta: 0.014000 % 5.147059
60 delta: 0.013000 % 4.779412
61 delta: 0.014000 % 5.147059
62 delta: 0.013000 % 4.779412
63 delta: 0.013000 % 4.761905
64 delta: 0.014000 % 5.147059
65 delta: 0.013000 % 4.779412
66 delta: 0.012000 % 4.411765
67 delta: 0.013000 % 4.797048
68 delta: 0.013000 % 4.779412
69 delta: 0.015000 % 5.494505
70 delta: 0.011000 % 4.044118
71 delta: 0.014000 % 5.147059
72 delta: 0.015000 % 5.494505
73 delta: 0.013000 % 4.779412
74 delta: 0.015000 % 5.494505
75 delta: 0.013000 % 4.779412
76 delta: 0.016000 % 5.860806
77 delta: 0.015000 % 5.514706
78 delta: 0.014000 % 5.147059
79 delta: 0.013000 % 4.779412
80 delta: 0.015000 % 5.494505
81 delta: 0.016000 % 5.818182
82 delta: 0.013000 % 4.761905
83 delta: 0.013000 % 4.779412
84 delta: 0.016000 % 5.860806
85 delta: 0.012000 % 4.411765
86 delta: 0.013000 % 4.779412
87 delta: 0.014000 % 5.128205
88 delta: 0.015000 % 5.514706
89 delta: 0.012000 % 4.411765
90 delta: 0.014000 % 5.147059
91 delta: 0.015000 % 5.494505
92 delta: 0.014000 % 5.147059
93 delta: 0.016000 % 5.860806
94 delta: 0.017000 % 6.204380
95 delta: 0.014000 % 5.147059
96 delta: 0.014000 % 5.147059
97 delta: 0.013000 % 4.779412
98 delta: 0.012000 % 4.411765
99 delta: 0.012000 % 4.411765
100 delta: 0.015000 % 5.494505
average percents is: 5.1020022

Здесь результаты не столь впечатляющие, как в предыдущем тесте, но тем не менее разница в ~5% есть.
Вывод: локальные переменные — наши друзья.

Вопросы производительности — 2

Posted in Uncategorized by ilovelua on 17 сентября, 2012

К вопросу о том, стоит ли заводить отдельные поля в модуле или пользоваться локальными переменными внутри модуля.

Код модуля:

module('TestModule', package.seeall)

local localTable = {}
testTable = {}

local count = 1000000

-- добавляем в модуль полей, чтобы поиск осуществлялся не в совсем пустой таблице
for i = 1, 100 do
    _M['testTable' .. i] = i
end

function fillTestTable()
    for i = 1, count do 
        testTable[i] = i
    end
end

function fillLocalTable()
    for i= 1, count do 
        localTable[i] = i
    end
end

Код теста:

local TestModule = require('TestModule')

function test()
    local t = os.clock ()
    TestModule.fillTestTable()
    local t1 = os.clock () - t

    t = os.clock ()
    TestModule.fillLocalTable()
    local t2 = os.clock () - t

    return t1, t2
end

local percents = {}

for i = 1, 100 do
    local t1, t2 = test()
    local delta = string.format('%.6f', t1 - t2)
    local p = string.format('%.6f', ((t1 - t2) / t1) * 100)

    print(i, 'delta:', delta, '%', p)

    table.insert(percents, p)
end

local totalPercents = 0

for i, percent in ipairs(percents) do
    totalPercents = totalPercents + percent
end

print('average percents is:', totalPercents / #percents)

Результаты:

1 delta: 0.020000 % 15.748031
2 delta: 0.023000 % 22.549020
3 delta: 0.022000 % 21.782178
4 delta: 0.022000 % 21.782178
5 delta: 0.022000 % 21.782178
6 delta: 0.022000 % 21.782178
7 delta: 0.022000 % 21.782178
8 delta: 0.021000 % 20.792079
9 delta: 0.021000 % 20.792079
10 delta: 0.021000 % 20.792079
11 delta: 0.021000 % 20.792079
12 delta: 0.023000 % 22.549020
13 delta: 0.021000 % 20.792079
14 delta: 0.023000 % 22.549020
15 delta: 0.022000 % 21.782178
16 delta: 0.023000 % 22.549020
17 delta: 0.023000 % 22.549020
18 delta: 0.023000 % 22.549020
19 delta: 0.021000 % 20.792079
20 delta: 0.023000 % 22.330097
21 delta: 0.021000 % 20.792079
22 delta: 0.022000 % 21.782178
23 delta: 0.022000 % 21.782178
24 delta: 0.021000 % 20.792079
25 delta: 0.023000 % 22.549020
26 delta: 0.021000 % 20.792079
27 delta: 0.022000 % 21.568627
28 delta: 0.022000 % 21.568627
29 delta: 0.024000 % 23.076923
30 delta: 0.022000 % 21.782178
31 delta: 0.021000 % 20.792079
32 delta: 0.022000 % 21.782178
33 delta: 0.023000 % 22.549020
34 delta: 0.022000 % 21.782178
35 delta: 0.022000 % 21.782178
36 delta: 0.022000 % 21.782178
37 delta: 0.022000 % 21.782178
38 delta: 0.022000 % 21.782178
39 delta: 0.021000 % 20.792079
40 delta: 0.022000 % 21.782178
41 delta: 0.021000 % 20.792079
42 delta: 0.022000 % 21.782178
43 delta: 0.022000 % 21.782178
44 delta: 0.022000 % 21.782178
45 delta: 0.020000 % 19.801980
46 delta: 0.022000 % 21.782178
47 delta: 0.023000 % 22.549020
48 delta: 0.022000 % 21.782178
49 delta: 0.022000 % 21.782178
50 delta: 0.022000 % 21.782178
51 delta: 0.023000 % 22.549020
52 delta: 0.022000 % 21.782178
53 delta: 0.022000 % 21.782178
54 delta: 0.022000 % 21.782178
55 delta: 0.021000 % 20.792079
56 delta: 0.022000 % 21.782178
57 delta: 0.022000 % 21.782178
58 delta: 0.022000 % 21.782178
59 delta: 0.022000 % 21.782178
60 delta: 0.021000 % 20.792079
61 delta: 0.020000 % 20.000000
62 delta: 0.022000 % 21.782178
63 delta: 0.022000 % 21.782178
64 delta: 0.021000 % 20.792079
65 delta: 0.022000 % 21.782178
66 delta: 0.021000 % 20.792079
67 delta: 0.022000 % 21.782178
68 delta: 0.022000 % 21.782178
69 delta: 0.021000 % 20.792079
70 delta: 0.022000 % 21.782178
71 delta: 0.022000 % 21.782178
72 delta: 0.022000 % 21.782178
73 delta: 0.022000 % 21.782178
74 delta: 0.022000 % 21.782178
75 delta: 0.022000 % 21.782178
76 delta: 0.021000 % 20.792079
77 delta: 0.022000 % 21.782178
78 delta: 0.022000 % 21.782178
79 delta: 0.022000 % 21.782178
80 delta: 0.023000 % 22.549020
81 delta: 0.022000 % 21.782178
82 delta: 0.022000 % 21.782178
83 delta: 0.023000 % 22.549020
84 delta: 0.022000 % 21.782178
85 delta: 0.023000 % 22.549020
86 delta: 0.022000 % 21.782178
87 delta: 0.022000 % 21.782178
88 delta: 0.022000 % 21.782178
89 delta: 0.022000 % 21.782178
90 delta: 0.022000 % 21.782178
91 delta: 0.023000 % 22.549020
92 delta: 0.022000 % 21.782178
93 delta: 0.022000 % 21.782178
94 delta: 0.022000 % 21.782178
95 delta: 0.022000 % 21.782178
96 delta: 0.022000 % 21.782178
97 delta: 0.021000 % 20.792079
98 delta: 0.022000 % 21.782178
99 delta: 0.022000 % 21.782178
100 delta: 0.022000 % 21.568627
average percents is: 21.61547195

Вывод: обращение к локальным переменным на ~20% быстрее, чем к полям модуля.
Локальные переменные — наши друзья.

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

Posted in Uncategorized by ilovelua on 11 сентября, 2012

Стало мне тут интересно, насколько в модулях Lua передача таблицы в качестве параметра в функцию быстрее, чем поиск таблицы по имени внутри модуля. Для этого был сооружен тестовый модуль TestModule.lua:

module('TestModule', package.seeall)

testTable = {}

local count = 1000000

-- добавляем в модуль полей, чтобы поиск осуществлялся не в пустой таблице
for i = 1, 100 do
    _M['testTable' .. i] = i
end

function fillTestTableStraight()
    local f = function(i)
        testTable[i] = i
    end

    for i = 1, count do
        f(i)
    end
end

function fillTestTableFromStack()
    local f = function(t, i)
        t[i] = i
    end

    for i = 1, count do
        f(testTable, i)
    end
end

А вот код теста:

local TestModule = require('TestModule')

function test()
    local t = os.clock ()
    TestModule.fillTestTableStraight()
    local t1 = os.clock () - t

    t = os.clock ()
    TestModule.fillTestTableFromStack()
    local t2 = os.clock () - t

    return t1, t2
end

local percents = {}

for i = 1, 100 do
    local t1, t2 = test()
    local delta = string.format('%.6f', t1 - t2)
    local p = string.format('%.6f', ((t1 - t2) / t1) * 100)

    print(i, 'delta:', delta, '%', p)

    table.insert(percents, p)
end

local totalPercents = 0

for i, percent in ipairs(percents) do
    totalPercents = totalPercents + percent
end

print('average percents is:', totalPercents / #percents)

Вот результаты:

1 delta: 0.038000 % 14.728682
2 delta: 0.009000 % 3.913043
3 delta: 0.010000 % 4.329004
4 delta: 0.008000 % 3.508772
5 delta: 0.008000 % 3.508772
6 delta: 0.008000 % 3.508772
7 delta: 0.007000 % 3.070175
8 delta: 0.007000 % 3.083700
9 delta: 0.007000 % 3.070175
10 delta: 0.007000 % 3.083700
11 delta: 0.008000 % 3.508772
12 delta: 0.008000 % 3.508772
13 delta: 0.008000 % 3.508772
14 delta: 0.008000 % 3.508772
15 delta: 0.007000 % 3.083700
16 delta: 0.003000 % 1.315789
17 delta: 0.016000 % 6.779661
18 delta: 0.007000 % 3.070175
19 delta: 0.008000 % 3.508772
20 delta: 0.007000 % 3.083700
21 delta: 0.010000 % 4.366812
22 delta: 0.008000 % 3.508772
23 delta: 0.008000 % 3.508772
24 delta: 0.007000 % 3.070175
25 delta: 0.009000 % 3.930131
26 delta: 0.011000 % 4.761905
27 delta: 0.008000 % 3.508772
28 delta: 0.007000 % 3.083700
29 delta: 0.006000 % 2.643172
30 delta: 0.008000 % 3.508772
31 delta: 0.008000 % 3.508772
32 delta: 0.007000 % 3.070175
33 delta: 0.007000 % 3.083700
34 delta: 0.008000 % 3.508772
35 delta: 0.007000 % 3.083700
36 delta: 0.008000 % 3.508772
37 delta: 0.007000 % 3.083700
38 delta: 0.008000 % 3.508772
39 delta: 0.008000 % 3.508772
40 delta: 0.007000 % 3.083700
41 delta: 0.008000 % 3.508772
42 delta: 0.007000 % 3.056769
43 delta: 0.008000 % 3.508772
44 delta: 0.007000 % 3.083700
45 delta: 0.009000 % 3.930131
46 delta: 0.007000 % 3.083700
47 delta: 0.007000 % 3.083700
48 delta: 0.009000 % 3.947368
49 delta: 0.008000 % 3.508772
50 delta: 0.009000 % 3.947368
51 delta: 0.008000 % 3.508772
52 delta: 0.008000 % 3.508772
53 delta: 0.008000 % 3.508772
54 delta: 0.007000 % 3.083700
55 delta: 0.007000 % 3.083700
56 delta: 0.008000 % 3.508772
57 delta: 0.008000 % 3.508772
58 delta: 0.008000 % 3.508772
59 delta: 0.008000 % 3.508772
60 delta: 0.009000 % 3.947368
61 delta: 0.008000 % 3.508772
62 delta: 0.007000 % 3.083700
63 delta: 0.009000 % 3.930131
64 delta: 0.006000 % 2.643172
65 delta: 0.007000 % 3.070175
66 delta: 0.008000 % 3.508772
67 delta: 0.008000 % 3.508772
68 delta: 0.008000 % 3.508772
69 delta: 0.006000 % 2.643172
70 delta: 0.010000 % 4.366812
71 delta: 0.008000 % 3.508772
72 delta: 0.007000 % 3.083700
73 delta: 0.009000 % 3.947368
74 delta: 0.008000 % 3.508772
75 delta: 0.008000 % 3.508772
76 delta: 0.007000 % 3.083700
77 delta: 0.009000 % 3.930131
78 delta: 0.008000 % 3.524229
79 delta: 0.009000 % 3.947368
80 delta: 0.009000 % 3.947368
81 delta: 0.008000 % 3.508772
82 delta: 0.009000 % 3.947368
83 delta: 0.008000 % 3.508772
84 delta: 0.007000 % 3.083700
85 delta: 0.007000 % 3.083700
86 delta: 0.007000 % 3.083700
87 delta: 0.008000 % 3.508772
88 delta: 0.008000 % 3.508772
89 delta: 0.007000 % 3.083700
90 delta: 0.007000 % 3.083700
91 delta: 0.008000 % 3.508772
92 delta: 0.006000 % 2.620087
93 delta: 0.044000 % 16.666667
94 delta: 0.008000 % 3.508772
95 delta: 0.010000 % 4.347826
96 delta: 0.008000 % 3.508772
97 delta: 0.007000 % 3.083700
98 delta: 0.008000 % 3.508772
99 delta: 0.008000 % 3.508772
100 delta: 0.008000 % 3.508772
average percents is: 3.6979102

Я несколько раз запускал этот тест, и результаты крутятся около 3.5%.

Ну, разница, понятно, не велика. Однако она есть. Чтобы почувствовать, насколько плох поиск по ключу в цикле, нужно воспользоваться локальными переменными. Поменяем в модуле TestModule функцию fillTestTableFromStack():

function fillTestTableFromStack()
    local f = function(t, i)
        t[i] = i
    end

    local tbl = testTable

    for i = 1, count do
        f(tbl, i)
    end
end

Результаты впечатляют гораздо сильнее:
1 delta: 0.037000 % 14.682540
2 delta: 0.038000 % 16.379310
3 delta: 0.033000 % 14.473684
4 delta: 0.037000 % 16.086957
5 delta: 0.033000 % 14.601770
6 delta: 0.037000 % 16.157205
7 delta: 0.036000 % 15.789474
8 delta: 0.033000 % 14.537445
9 delta: 0.033000 % 14.601770
10 delta: 0.035000 % 15.486726
11 delta: 0.035000 % 15.418502
12 delta: 0.032000 % 14.096916
13 delta: 0.034000 % 14.977974
14 delta: 0.034000 % 15.044248
15 delta: 0.033000 % 14.666667
16 delta: 0.035000 % 15.418502
17 delta: 0.035000 % 15.418502
18 delta: 0.030000 % 13.043478
19 delta: 0.036000 % 15.789474
20 delta: 0.035000 % 15.418502
21 delta: 0.034000 % 15.044248
22 delta: 0.034000 % 15.111111
23 delta: 0.036000 % 15.789474
24 delta: 0.035000 % 15.418502
25 delta: 0.035000 % 15.418502
26 delta: 0.035000 % 15.418502
27 delta: 0.035000 % 15.418502
28 delta: 0.034000 % 15.044248
29 delta: 0.034000 % 15.044248
30 delta: 0.036000 % 15.859031
31 delta: 0.034000 % 15.044248
32 delta: 0.035000 % 15.418502
33 delta: 0.035000 % 15.418502
34 delta: 0.033000 % 14.666667
35 delta: 0.034000 % 15.044248
36 delta: 0.034000 % 15.044248
37 delta: 0.034000 % 15.044248
38 delta: 0.035000 % 15.418502
39 delta: 0.035000 % 15.418502
40 delta: 0.033000 % 14.666667
41 delta: 0.034000 % 15.044248
42 delta: 0.035000 % 15.418502
43 delta: 0.036000 % 15.789474
44 delta: 0.035000 % 15.418502
45 delta: 0.032000 % 14.159292
46 delta: 0.033000 % 14.666667
47 delta: 0.035000 % 15.418502
48 delta: 0.035000 % 15.418502
49 delta: 0.036000 % 15.789474
50 delta: 0.036000 % 15.859031
51 delta: 0.035000 % 15.418502
52 delta: 0.034000 % 15.044248
53 delta: 0.037000 % 16.228070
54 delta: 0.036000 % 15.789474
55 delta: 0.037000 % 16.228070
56 delta: 0.035000 % 15.418502
57 delta: 0.035000 % 15.486726
58 delta: 0.034000 % 15.044248
59 delta: 0.034000 % 15.044248
60 delta: 0.036000 % 15.789474
61 delta: 0.034000 % 15.044248
62 delta: 0.037000 % 16.228070
63 delta: 0.034000 % 15.044248
64 delta: 0.035000 % 15.486726
65 delta: 0.036000 % 15.859031
66 delta: 0.034000 % 15.044248
67 delta: 0.035000 % 15.350877
68 delta: 0.037000 % 16.228070
69 delta: 0.034000 % 15.044248
70 delta: 0.034000 % 15.111111
71 delta: 0.037000 % 16.228070
72 delta: 0.036000 % 15.859031
73 delta: 0.037000 % 16.228070
74 delta: 0.036000 % 15.859031
75 delta: 0.035000 % 15.418502
76 delta: 0.036000 % 15.859031
77 delta: 0.036000 % 15.789474
78 delta: 0.034000 % 15.044248
79 delta: 0.034000 % 15.044248
80 delta: 0.035000 % 15.418502
81 delta: 0.035000 % 15.486726
82 delta: 0.035000 % 15.418502
83 delta: 0.035000 % 15.486726
84 delta: 0.034000 % 15.044248
85 delta: 0.037000 % 16.228070
86 delta: 0.034000 % 15.044248
87 delta: 0.035000 % 15.418502
88 delta: 0.034000 % 15.044248
89 delta: 0.034000 % 15.044248
90 delta: 0.035000 % 15.418502
91 delta: 0.040000 % 17.167382
92 delta: 0.038000 % 16.593886
93 delta: 0.034000 % 15.044248
94 delta: 0.035000 % 15.418502
95 delta: 0.034000 % 15.044248
96 delta: 0.034000 % 15.044248
97 delta: 0.033000 % 14.666667
98 delta: 0.036000 % 15.789474
99 delta: 0.038000 % 16.593886
100 delta: 0.034000 % 15.044248
average percents is: 15.36543997

Вывод: локальные переменные — наши друзья.