[erlang-questions] performance on multicore computer
Jesper Louis Andersen
jesper.louis.andersen@REDACTED
Sat Oct 23 02:40:21 CEST 2010
On Sat, Oct 23, 2010 at 1:07 AM, Jiansen He <jiansenhe@REDACTED> wrote:
This part:
> %% -- generate all sequences of length exactly n starting at index i or
> later
> %% gen_ :: Int -> Int -> [String] -> AssocList [String] Int
> gen_ (_, _, [], From) -> From ! {seq, []};
> gen_ (I, N, [H | T], From) ->
> if
> N > length([H | T]) -> From ! {seq, []};
> true ->
> gen_(I+1, N, T, self()),
> receive
> {seq, Seq} ->
> From ! {seq, insert({takeN(N, [H | T]), I}, Seq)};
> Msg ->
> io:format("unrecognized message in gen_/4: ~n")
> end
> end.
Seem a bit odd to me. If I read it right, you are essentially running
a recursive loop by messaging yourself the result of the recursive
calls. In other words I think you can rewrite this into a normal
recursive loop. This will definitely be faster as the receives simply
serialize into a long chain, the mailbox only containing a single
message all the time.
> %% -- generate all sequences of length at most n
> %% gen :: Int -> [String] -> AssocList [String] Int
> gen(0, _, From) ->
> From ! {seq, []};
> gen(N, L, From) ->
> spawn(concordance_1_1, gen_, [0, N, L, self()]),
> spawn(concordance_1_1, gen, [(N-1), L, self()]),
> gen_loop(2, [], From).
>
> gen_loop(0, Seq, From) ->
> From ! {seq, Seq};
> gen_loop(N, Seq, From) ->
> receive
> {seq, Seq_} ->
> gen_loop(N-1, merge(Seq, Seq_), From);
> Msg ->
> io:format("f unrecognized message in gen_loop/3: ")
> end.
These seem ok from a quick glance. And they seem to be in accordance
with the Haskell code below.
> In Haskell, I could simply write code like this:
>
> -- generate all sequences of length at most n
> gen :: Int -> [String] -> AssocList [String] Int
> gen 0 _ = []
> --gen n l = merge sqs_len_n sqs_up_to_n1
> gen n l = sqs_len_n `par` sqs_up_to_n1 `pseq` (merge sqs_len_n sqs_up_to_n1)
> where sqs_up_to_n1 = (gen (n-1) l)
> sqs_len_n = (gen' 0 n l)
The `par` combinator is perhaps mostly akin to the rpc:parallel_eval/1
call in the Erlang/OTP stdlib by the way. Note however that
parallel_eval can span multiple machines (nodes in Erlang-terminology)
in a distributed fashion, which `par` cannot. Also, by using parallel
eval, you could eliminate the gen_loop from your code and fold the
merge into gen like in the Haskell version.
--
J.
More information about the erlang-questions
mailing list