3

これら2つのうち、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> 

ところで、コンパイラが test_1 の ValueA バインディングをデッド コードとして扱わないように、「ValueA + ValueB」式を追加する必要がありました。それを外すと、その分タイムに大きな差が出ます。

于 2013-05-08T16:31:23.830 に答える