Страницы

вторник, 17 января 2012 г.

Скорость работы Erlang -а

Давно начал работать с Erlang-ом. В конце концов каждому программисту становится интересно скорость работы того или иного языка. Пишем набор простых тестов.
Скорость выполнения отдельной операции это конечно интересно, но чаще всего любая операция работает вместе с вызовом какой-то функции. В итоге пишем что-то типа этого


-module(meash_loop).
-export([loop/2]).

loop(Fun,List) when is_list(List) ->
First=now(),
lists:map(Fun,List),
Second=now(),
timer:now_diff(Second,First)
;

loop(Fun,Num)->
First=now(),
lists:map(Fun,lists:seq(1, Num) ),
Second=now(),
timer:now_diff(Second,First)
.


Аргумент функции указатель на функцию и кол-во раз сколько прогнать все это дело. Дальше компилируем и открываем консоль. Сразу скажу тестил на обычном ноутбуке
Linux user-Vostro-1015 2.6.35-22-generic #35-Ubuntu SMP Sat Oct 16 20:36:48 UTC 2010 i686 GNU/Linux
Памяти 2 GB Intel Core 2 Duo.

Дальше открываем консольку и смотрим результат в микросекундах это -6 степень ;)

1> Fun=fun(Elem)-> Elem*Elem end.
#Fun
2> Fun(1).
1
3> Fun(2).
4
4> meash_loop:loop(Fun,100000).
482771
5> meash_loop:loop(Fun,1000000).
6521603
6> meash_loop:loop(Fun,10000).
49287
7> meash_loop:loop(Fun,1000).
4711
8> meash_loop:loop(Fun,1000).
4748
9> meash_loop:loop(Fun,1000).
8780


Окей а давайте возведем в третью степень :

Fun1=fun(Elem)-> Elem*Elem*Elem end.
#Fun
13> meash_loop:loop(Fun1,100000).
932604
14> meash_loop:loop(Fun1,1000).
6711
15> meash_loop:loop(Fun1,10000).
54362
16> meash_loop:loop(Fun1,100000).
752449
17> meash_loop:loop(Fun1,100000).
744842


Теперь тест более приближенный к реальности, посмотрим скорость вставки в ets таблицу, причем функция еще и будет преобразовывать число в строку..
ets:new(test,[ set , public,named_table]).
test
19> Fun2=fun(Elem)-> F=integer_to_list(Elem),ets:insert(test,{F,something}) end.
#Fun
20> Fun2(3).
true
21> ets:lookup(test,"3").
[{"3",something}]
22> meash_loop:loop(Fun2,100000).
1302136
23> meash_loop:loop(Fun2,10000).
121003
24> meash_loop:loop(Fun2,1000000).
13544228
25> halt().

Миллион записей за 13 секунд... Ладно тогда посмотрим, как он будет выбирать эти записи



1> ets:new(test,[ set , public,named_table]).
test
2> Fun2=fun(Elem)-> F=integer_to_list(Elem),ets:insert(test,{F,something}) end.
#Fun
3> Fun1=fun(Elem)-> F=integer_to_list(Elem),ets:lookup(test,F) end.
#Fun
4> meash_loop:loop(Fun2,100000). % сначала их вставим
1264420
5>

5> meash_loop:loop(Fun1,100000).%а потом достанем
1121538
6> meash_loop:loop(Fun1,100000).%немного лучше
1066490
7> meash_loop:loop(Fun1,100000).%но результат -> const
1072915
8> meash_loop:loop(Fun1,100000).%результат -> const
1103442
9> meash_loop:loop(Fun1,100000).
1108888
10> meash_loop:loop(Fun2,1000000).% Теперь миллион
13525837
11> meash_loop:loop(Fun1,1000000).%Достаем
11573639
12> meash_loop:loop(Fun1,1000000).%
12064171

12 -11.5 секунд он вам миллиончик и выберет



Как будет настроение продолжим...
Далее будем пытаться выяснить принципиальный вопрос, что лучше использовать pattern matching,case, dict или еще что-то там

Комментариев нет: