3

这两者中哪一个在 Erlang 中效率更高?这个:

ValueA = MyRecord#my_record.value_a,
ValueB = MyRecord#my_record.value_b.

或这个:

{ValueA, ValueB} = {MyRecord#my_record.value_a, MyRecord#my_record.value_b}.

?

我问是因为后者有时会让我需要多行来适应我喜欢保留的 80 个字符的行长度限制,而且我倾向于避免做这样的事情:

{ValueA, ValueB} = { MyRecord#my_record.value_a
                   , MyRecord#my_record.value_b }.
4

2 回答 2

4

它们生成完全相同的代码!如果您想要更少的代码,请尝试使用:

#my_record{value_a=ValueA,value_b=ValueB} = MyRecord

这也会生成相同的代码。通常,如果可以,请使用模式匹配。它永远不会更糟,通常会更好。在这种情况下,他们都做了必要的最小工作量。

一般来说,编写最清晰、看起来最好的代码,只有在您知道此代码存在速度问题时才担心这些类型的优化。

于 2013-05-08T18:55:49.160 回答
2

我做了一个小测试,似乎它们大致相同:

-module(timeit).
-export([test/0]).

-record(my_record, {value_a, value_b}).

times(N, Fn) ->
    fun () -> do_times(N, Fn) end.

do_times(0, _Fn) ->
    ok;
do_times(N, Fn) ->
    Fn(),
    do_times(N-1, Fn).

test_1() ->
    MyRecord = #my_record{value_a=1, value_b=2},
    timer:tc(times(100000000,
       fun () ->
           ValueA = MyRecord#my_record.value_a,
           ValueB = MyRecord#my_record.value_b,
           ValueA + ValueB
       end)).

test_2() ->
    MyRecord = #my_record{value_a=1, value_b=2},
    timer:tc(times(100000000,
       fun () ->
           {ValueA, ValueB} = { MyRecord#my_record.value_a,
                                MyRecord#my_record.value_b },
           ValueA + ValueB
       end)).

test() ->
    {test_1(), test_2()}.

44> timeit:test().
{{6042747,ok},{6063557,ok}}
45> timeit:test().
{{5849173,ok},{5822836,ok}}
46> 

顺便说一句,我必须添加“ValueA + ValueB”表达式,以便编译器不会将 test_1 中的 ValueA 绑定视为死代码。如果您删除它,您会因此看到时代的巨大差异。

于 2013-05-08T16:31:23.830 回答