从erlang进程循环中获取值的优化方法

时间:2013-09-15 06:13:18

标签: erlang

嗨,我是Erlang的新手,我刚开始学习流程。这里我有一个典型的流程循环:

loop(X,Y,Z) ->
    receive
        {do} ->
            NewX = X+1,
            NewY = Y+1,
            NewZ = Z+1,

            Product = NewX * NewY * NewZ,

            % do something

            loop(NewX,NewY,NewZ)
    end.

如何从函数Product获取get_product()的最新值?我知道消息传递将是逻辑选项,但是有更优化的方法来提取值吗?

2 个答案:

答案 0 :(得分:2)

假设这就是你想要的:

-module(lab).

-compile(export_all).

start() ->
    InitialState = {1,1,1},
    Pid = spawn(?MODULE, loop, [InitialState]),
    register(server, Pid).

loop(State) ->
    {X, Y, Z} = State,
    receive
        tick ->
            NewX = X+1,
            NewY = Y+1,
            NewZ = Z+1,
            NewState = {NewX, NewY, NewZ},
            loop(NewState);
        {get_product, From} ->
            Product = X * Y * Z,
            From ! Product,
            loop(State);
        _ ->
            io:format("Unknown message received.~n"),
            loop(State)
    end.

get_product() ->
    server ! {get_product, self()},
    receive
        Product ->
            Product
    end.

tick() ->
    server ! tick.

从Erlang shell中:

1> c(lab).
{ok,lab}
2> lab:start().
true
3> lab:get_product().
1
4> lab:tick().       
tick
5> lab:get_product().
8
6> lab:tick().       
tick
7> lab:tick().
tick
8> lab:get_product().
64

答案 1 :(得分:2)

以下是我所知道的Erlang进程之间的通信方法,以及我(可能是错误的)对其相对性能的评估。

  1. Message passing 即可。此方法将满足您的大多数需求。我不知道它是如何实现的,但从我的观点来看,它应该像将指针放入队列并将其检索回来一样快。
  2. 外部方法,例如socketsfilespipes 。这些方法可能更快地在不同节点之间进行通信,具体取决于您解决的问题,您的解决方案以及您的程序将执行的环境.Erlang中的节点间通信是通过TCP连接完成的,因此如果您想使用自编写的代码要通过TCP套接字进行通信,你应该非常努力地超越Erlang的实现。
  3. ETSDets 。假设最佳实现方式,这些方法不会比消息传递(ETS)或文件(Dets)快。
  4. NIF 即可。您可以编写一种方法来保存NIF库中的值,另一种方法可以检索它。这个有可能超越消息传递,因为您只需将值保存到变量中并在需要时将其返回,并且receive中的模式匹配没有任何开销。
  5. Process dictionary 即可。您可以使用erlang:process_info(Pid, dictionary)调用获取另一个流程词典,在Pid流程中,您可以使用put(Key, Value)调用将值放入该词典中。
  6. 此外,如果您想加快Erlang应用程序的速度,请查看HiPE,这可能有所帮助。

    在从消息传递切换到此列表中的任何内容之前,您应该首先测量