并发Prime发生器

Dan*_*Dan 6 concurrency erlang primes

我正在通过projecteuler.net上的问题来学习如何在Erlang中编程,并且我正在努力创建一个可以在不到一分钟内创建低于200万的所有素数的素数生成器.使用顺序样式,我已经编写了三种类型的生成器,包括Eratosthenes的Sieve,并且它们都没有表现得足够好.

我认为一个并发的Sieve会很好用,但我收到的是bad_arity消息,我不知道为什么.有关我遇到问题的原因或如何正确编码的任何建议?

这是我的代码,注释掉的部分是我试图让事情并发的地方:

-module(primeserver).
-compile(export_all).

start() ->
    register(primes, spawn(fun() -> loop() end)).

is_prime(N) -> rpc({is_prime,N}).

rpc(Request) ->
    primes ! {self(), Request},
    receive
        {primes, Response} ->
            Response
    end.

loop() ->
    receive
        {From, {is_prime, N}} ->
            if
                N  From ! {primes, false};
                N =:= 2 -> From ! {primes, true};
                N rem 2 =:= 0 -> From ! {primes, false};
                true ->
                    Values = is_not_prime(N),
                    Val = not(lists:member(true, Values)),
                    From ! {primes, Val}
            end,
            loop()
    end.

for(N,N,_,F) -> [F(N)];
for(I,N,S,F) when I + S  [F(I)|for(I+S, N, S, F)];
for(I,N,S,F) when I + S =:= N -> [F(I)|for(I+S, N, S, F)];
for(I,N,S,F) when I + S > N -> [F(I)].

get_list(I, Limit) ->
    if
        I 
            [I*A || A 
            []
    end.

is_not_prime(N) ->
    for(3, N, 2, 
        fun(I) -> 
            List = get_list(I,trunc(N/I)),
            lists:member(N,lists:flatten(List))
        end
        ).

    %%L = for(1,N, fun() -> spawn(fun(I) -> wait(I,N) end) end),
    %%SeedList = [A || A  
    %%      lists:foreach(fun(X) ->
    %%              Pid ! {in_list, X} 
    %%                end, SeedList)
    %%        end, L).

%%wait(I,N) ->
%%  List = [I*A || A  lists:member(X,List)
%%  end.

Hai*_*inh 7

我使用Go和渠道编写了一个Eratosthenesque并发主筛.

这是代码:http://github.com/aht/gosieve

我在这里写了博客:http://blog.onideas.ws/eratosthenes.go

该程序可以在大约10秒钟内筛选出第一批百万个素数(所有素数达到15,485,863).筛子是并发的,但算法主要是同步的:goroutines("actor" - 如果你愿意)之间需要太多同步点,因此它们不能并行自由漫游.


小智 3

“badarity”错误意味着您尝试使用错误数量的参数调用“fun”。在这种情况下...

%%L = for(1,N, fun() -> 产卵(fun(I) -> 等待(I,N) 结束) 结束),

for/3 函数期望 arity 1 的 fun,spawn/1 函数期望 arity 0 的 fun。请尝试以下操作:

L = for(1, N, fun(I) -> spawn(fun() -> wait(I, N) end) end),
Run Code Online (Sandbox Code Playgroud)

传递给spawn的乐趣继承了其环境的所需部分(即I),因此无需显式传递它。

虽然计算素数总是很有趣,但请记住,这不是 Erlang 旨在解决的问题。Erlang 是为大规模 Actor 式并发而设计的。它很可能在所有数据并行计算的例子上表现得相当糟糕。在许多情况下,ML 中的顺序解决方案速度非常快,任何数量的内核都不足以让 Erlang 赶上,例如F# 和 .NET 任务并行库肯定是此类解决方案的更好工具的操作。