欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

erlang 列表推导和递归哪个速度快?  

程序员文章站 2022-07-15 11:35:05
...

直接上代码:

-module (tl).

-export ([t1/0, t2/0]).

t1() ->
    [ X || X <- lists:seq(1, 5000) ].

t2() ->
    t2(lists:seq(1, 5000)).
t2([H|T]) ->
    H,
    t2(T);
t2([]) ->
    ok.

 tc代码:

%% ===================================================================
%% Author xiaotie
%% 2015-07-30
%% 单进程循环测试:LoopTimes是循环次数
%% tc:t(Module, Function, ArgsList, LoopTimes).
%% 多进程并发测试:SpawnProcessesCount是并发的进程数
%% tc:ct(Module, Function, ArgsList, SpawnProcessesCount).
%% ===================================================================

-module (tc).

-export ([t/4, ct/4]).


tc(M, F, A) ->
    {Microsecond, _} = timer:tc (M, F, A),
    Microsecond.

distribution(List, Aver) ->
    distribution(List, Aver, 0, 0).
distribution([H|T], Aver, Greater, Less) ->
    case H > Aver of
        true ->
            distribution(T, Aver, Greater + 1, Less);
        false ->
            distribution(T, Aver, Greater, Less + 1)
    end;
distribution([], _Aver, Greater, Less) ->
    {Greater, Less}.

%% ===================================================================
%% test: one process test N times
%% ===================================================================

t(M, F, A, N) ->
    {Max, Min, Sum, Aver, Greater, Less} = loop ({M, F, A}, N),
    io:format ("=====================~n"),
    io:format ("execute [~p] times of {~p, ~p, ~p}:~n", [N, M, F, A]),
    io:format ("Maximum: ~p(μs)\t~p(s)~n", [Max, Max / 1000000]),
    io:format ("Minimum: ~p(μs)\t~p(s)~n", [Min, Min / 1000000]),
    io:format ("Sum: ~p(μs)\t~p(s)~n", [Sum, Sum / 1000000]),
    io:format ("Average: ~p(μs)\t~p(s)~n", [Aver, Aver / 1000000]),
    io:format ("Greater: ~p~nLess: ~p~n", [Greater, Less]),
    io:format ("=====================~n").


loop({M, F, A}, N) ->
    loop ({M, F, A}, N, 1, 0, 0, 0, []).

loop({M, F, A}, N, I, Max, Min, Sum, List) when N >= I ->
    Microsecond = tc (M, F, A),
    NewSum = Sum + Microsecond,
    if
        Max == 0 ->
            NewMax = NewMin = Microsecond;
        Max < Microsecond ->
            NewMax = Microsecond,
            NewMin = Min;
        Min > Microsecond ->
            NewMax = Max,
            NewMin = Microsecond;
        true ->
            NewMax = Max,
            NewMin = Min
    end,
    loop ({M, F, A}, N, I + 1, NewMax, NewMin, NewSum, [Microsecond|List]);
loop({_M, _F, _A}, N, _I, Max, Min, Sum, List) ->
    Aver = Sum / N,
    {Greater, Less} = distribution(List, Aver),
    {Max, Min, Sum, Aver, Greater, Less}.

%% ===================================================================
%% Concurrency test: N processes each test one time
%% ===================================================================

ct(M, F, A, N) ->
    {Max, Min, Sum, Aver, Greater, Less} = cloop ({M, F, A}, N),
    io:format ("=====================~n"),
    io:format ("spawn [~p] processes of {~p, ~p, ~p}:~n", [N, M, F, A]),
    io:format ("Maximum: ~p(μs)\t~p(s)~n", [Max, Max / 1000000]),
    io:format ("Minimum: ~p(μs)\t~p(s)~n", [Min, Min / 1000000]),
    io:format ("Sum: ~p(μs)\t~p(s)~n", [Sum, Sum / 1000000]),
    io:format ("Average: ~p(μs)\t~p(s)~n", [Aver, Aver / 1000000]),
    io:format ("Greater: ~p~nLess: ~p~n", [Greater, Less]),
    io:format ("=====================~n").


cloop({M, F, A}, N) ->
    CollectorPid = self(),
    ok = loop_spawn({M, F, A}, CollectorPid, N),
    collector(0, 0, 0, N, 1, []).


loop_spawn({M, F, A}, CollectorPid, N) when N > 0 ->
    spawn_link(fun() -> worker({M, F, A}, CollectorPid) end),
    loop_spawn({M, F, A}, CollectorPid, N - 1);
loop_spawn(_, _, 0) ->
    ok.

collector(Max, Min, Sum, N, I, List) when N >= I ->
    receive
        {result, Microsecond} ->
            NewSum = Sum + Microsecond,
            if
                Max == 0 ->
                    NewMax = NewMin = Microsecond;
                Max < Microsecond ->
                    NewMax = Microsecond,
                    NewMin = Min;
                Min > Microsecond ->
                    NewMax = Max,
                    NewMin = Microsecond;
                true ->
                    NewMax = Max,
                    NewMin = Min
            end,
            collector(NewMax, NewMin, NewSum, N, I + 1, [Microsecond|List])
    after
        10000 ->
            ok
    end;
collector(Max, Min, Sum, N, _, List) ->
    Aver = Sum / N,
    {Greater, Less} = distribution(List, Aver),
    {Max, Min, Sum, Aver, Greater, Less}.


worker({M, F, A}, CollectorPid) ->
    Microsecond = tc(M, F, A),
    CollectorPid ! {result, Microsecond}.

 结果:

==> etoml (compile)
==> simple_im (compile)
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:false]

Eshell V7.0  (abort with ^G)
1> tc:t(tl, t1, [], 5000).
=====================
execute [5000] times of {tl, t1, []}:
Maximum: 357(μs)        3.57e-4(s)
Minimum: 98(μs) 9.8e-5(s)
Sum: 537592(μs) 0.537592(s)
Average: 107.5184(μs)   1.075184e-4(s)
Greater: 957
Less: 4043
=====================
2> tc:t(tl, t2, [], 5000).
=====================
execute [5000] times of {tl, t2, []}:
Maximum: 321(μs)        3.21e-4(s)
Minimum: 81(μs) 8.1e-5(s)
Sum: 431156(μs) 0.431156(s)
Average: 86.2312(μs)    8.62312e-5(s)
Greater: 1680
Less: 3320
=====================