[erlang-questions] Erlang shows its slow face!

Hynek Vychodil hynek@REDACTED
Sat Nov 13 20:30:18 CET 2010


On Sat, Nov 13, 2010 at 4:59 PM, Tony Rogvall <tony@REDACTED> wrote:
> Hi Gilberto!
>
> I did some rewrite of the FORM 2, that I think is more compatible with the condition that A+B+C =< N,
> and the result is of course much better. How did you implement the C# version ?
>
> My results for N = 300, times are measured with timer:tc.
>
> pythag0:                4837528         (4.8s)
> pythag1:                4289769         (4.3s)
> pythag2:                703632                  (0.7s)
>
> And the result with +native
>
> pythag0:                1006865         (1.0s)
> pythag1:                441254                  (0.4s)
> pythag2:                107387                  (0.1s)
>
> /Tony
>
> My versions (original + the version that only generates the list once)
>
> -module(pythag).
>
> -compile(export_all).
>
> pythag0(N) ->
>    [ {A,B,C} ||
>        A <- lists:seq(1,N),
>        B <- lists:seq(1,N),
>        C <- lists:seq(1,N),
>        A+B+C =< N,
>        A*A+B*B =:= C*C].
>
> pythag1(N) ->
>    L = lists:seq(1,N),
>    [ {A,B,C} ||
>        A <- L,
>        B <- L,
>        C <- L,
>        A+B+C =< N,
>        A*A+B*B =:= C*C].
>
>
> pythag2(N) ->
>    lists:reverse(pythan2_A(1, N, [])).
>
> pythan2_A(A, N, Acc) when A > N -> Acc;
> pythan2_A(A, N, Acc) -> pythan2_A(A+1,N,pythan2_B(A, 1, N, Acc)).
>
> pythan2_B(A, B, N, Acc) when A+B > N -> Acc;
> pythan2_B(A, B, N, Acc) -> pythan2_B(A,B+1,N,pythan2_C(A, B, 1, N, Acc)).
>
> pythan2_C(A, B, C, N, Acc) when A+B+C > N -> Acc;
> pythan2_C(A, B, C, N, Acc) ->
>    if A*A+B*B =:= C*C ->
>            pythan2_C(A, B, C+1, N, [{A,B,C}|Acc]);
>       true ->
>            pythan2_C(A, B, C+1, N, Acc)
>    end.
>
>

Simpler and about 5% faster version:

pythag3(N) when is_integer(N) -> pythag3(N,1).

pythag3(N, A) when A+2 > N -> [];
pythag3(N, A) -> pythag3(N, A, 1).

pythag3(N, A, B) when A+B+1 > N -> pythag3(N, A+1);
pythag3(N, A, B) -> pythag3(N, A, B, 1).

pythag3(N, A, B, C) when A+B+C > N -> pythag3(N, A, B+1);
pythag3(N, A, B, C) when A*A + B*B =:= C*C -> [{A, B, C}|pythag3(N, A, B, C+1)];
pythag3(N, A, B, C) -> pythag3(N, A, B, C+1).
>
>
>
> On 13 nov 2010, at 08.37, Gilberto Carmenate García wrote:
>
>> Hi all!
>> I have been doing tests to Erlang I found this funny stuff that makes
>> Pythagorean Triplets
>>
>> pythag(N) ->
>>    [ {A,B,C} ||
>>        A <- lists:seq(1,N),
>>        B <- lists:seq(1,N),
>>        C <- lists:seq(1,N),
>>        A+B+C =< N,
>>        A*A+B*B =:= C*C].
>>
>> I tested it agains an implementation I made in C# so, and takes 14
>> secounds in my pc to do with 300 numbers in Erlang however in c# is just
>> a secound, even when C# runs under VM too.
>> So I did all possible ways for me to implement differents manners in
>> Erlang looking for speed and all is the same, listed as  follows:
>>
>> So my question is, there are any way to do that even more fast, why 3
>> nestes fors structs in C# are more effients that lists:foldr or
>> lists:foreach in Erlang.
>>
>> %% FORMA 1
>> py1(Max)->
>>    L = lists:seq(1, Max),
>>    lists:foldr(
>>        fun(A, Acc3)->
>>            lists:foldr(
>>                fun(B, Acc2)->
>>                    lists:foldr(
>>                        fun(C, Acc)->
>>                            case ((A*A + B*B =:= C*C) andalso (A+B+C =<
>> Max)) of
>>                                                               true->
>>                                    [{A,B,C}|Acc];
>>                                false->
>>                                    Acc
>>                            end
>>                        end
>>                    , Acc2, L)
>>                end
>>            , Acc3, L)
>>        end
>>    , [], L).
>>
>>
>>
>> %% FORMA 2
>> py2(Max)->
>>       fora(1, [], Max).
>>
>> fora(A, Acc, Max)->
>>       Acc1 = forb(A,1, Acc, Max),
>>       case A < Max of
>>        true->
>>            fora(A+1, Acc1, Max);
>>        false->
>>            Acc1
>>    end.
>>
>> forb(A,B, Acc, Max)->
>>    Acc1 = forc(A,B,1, Acc, Max),
>>    case B < Max of
>>        true->
>>            forb(A,B+1, Acc1, Max);
>>        false->
>>            Acc1
>>    end.
>>
>> forc(A,B,C, Acc, Max)->
>>    Acc1 = case (A*A + B*B =:= C*C) andalso (A+B+C =< Max) of
>>        true->
>>            [{A,B,C}|Acc];
>>        _->
>>            Acc
>>    end,
>>    case C < Max of
>>        true->
>>            forc(A,B,C+1, Acc1, Max);
>>        false->
>>            Acc1
>>    end.
>>
>> %% FORMA 3.
>> py3(Max)->
>>       [{A,B,C} ||
>>               A <-lists:seq(1, Max),
>>               B <-lists:seq(1, Max),
>>               C <-lists:seq(1, Max),
>>               A*A + B*B =:= C*C,
>>               A+B+C =< Max].
>>
>>
>> =======================================================================
>> Este mensaje ha sido enviado mediante el servicio de correo electronico que ofrece la Federacion de Radioaficionados de Cuba a sus miembros para respaldar el cumplimiento de los objetivos de la organizacion y su politica informativa. La persona que envia este correo asume el compromiso de  usar el servicio a tales fines y cumplir con las regulaciones establecidas.
>>
>>
>>
>> ________________________________________________________________
>> erlang-questions (at) erlang.org mailing list.
>> See http://www.erlang.org/faq.html
>> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>>
>
> "Have run Make so many times I dunno what's installed anymore"
>
>



-- 
--Hynek (Pichi) Vychodil

Analyze your data in minutes. Share your insights instantly. Thrill
your boss.  Be a data hero!
Try GoodData now for free: www.gooddata.com


More information about the erlang-questions mailing list