[erlang-questions] Why does Erlang have control structures?

Jayson Barley jayson.barley@REDACTED
Tue Aug 28 00:47:27 CEST 2012


Thank you Paul. It appears to me that they don't compile down to the same
code. Am I missing something?

On Mon, Aug 27, 2012 at 3:35 PM, Paul Oliver <puzza007@REDACTED> wrote:

> You can use erlc +to_core to get the core erlang:
>
> module 'test' ['is_greater_than'/2,
>        'is_greater_than_control'/2,
>        'is_true'/1,
>        'module_info'/0,
>        'module_info'/1]
>     attributes []
> 'is_true'/1 =
>     %% Line 5
>     fun (_cor0) ->
> case _cor0 of
>   <'true'> when 'true' ->
>       %% Line 6
>       'true'
>   %% Line 7
>   <'false'> when 'true' ->
>       %% Line 8
>       'false'
>   ( <_cor1> when 'true' ->
> ( primop 'match_fail'
>       ({'function_clause',_cor1})
>   -| [{'function_name',{'is_true',1}}] )
>     -| ['compiler_generated'] )
> end
> 'is_greater_than'/2 =
>     %% Line 10
>     fun (_cor1,_cor0) ->
> let <_cor2> =
>     %% Line 11
>     call 'erlang':'>'
> (_cor1, _cor0)
> in  %% Line 11
>     apply 'is_true'/1
> (_cor2)
> 'is_greater_than_control'/2 =
>     %% Line 13
>     fun (_cor1,_cor0) ->
> %% Line 15
> case <> of
>   %% Line 16
>   <>
>       when call 'erlang':'>'
>     (_cor1,
>      _cor0) ->
>       %% Line 17
>       'true'
>   %% Line 18
>   <> when 'true' ->
>       %% Line 19
>       'false'
> end
> 'module_info'/0 =
>     fun () ->
> call 'erlang':'get_module_info'
>     ('test')
> 'module_info'/1 =
>     fun (_cor0) ->
> call 'erlang':'get_module_info'
>     ('test', _cor0)
> end
>
> On Mon, Aug 27, 2012 at 5:44 PM, Jayson Barley <jayson.barley@REDACTED>wrote:
>
>> That is interesting. I didn't know that. I wonder why over 100 million
>> iterations I consistently get between 1 to 2 second differences in timing.
>> I know that there will be differences due to garbage collection, other
>> processes running, etc, but the is_greater_than_control/2 function always
>> outperforms the is_greater_than/2 function. Am I making a wrong assumption
>> and eventually the opposite would be true? Could you test the below code on
>> your system and let me know if you get similar results?
>>
>> -module(test).
>> -compile(export_all).
>>
>>
>> is_true(true) ->
>>     true;
>> is_true(false) ->
>>     false.
>>
>> is_greater_than(X, Y) ->
>>     is_true(X>Y).
>>
>> is_greater_than_control(X, Y) ->
>>
>>     if
>>         X>Y ->
>>             true;
>>         true -> % works as an 'else' branch
>>             false
>>     end.
>>
>> test_if(X, X, _) ->
>>     done;
>> test_if(X, Max, Fun) ->
>>     Fun(X, Max),
>>     test_if(X + 1, Max, Fun).
>>
>> test_if(Max) ->
>>     [timer:tc(test, test_if, [0, Max, fun is_greater_than/2]),
>> timer:tc(test, test_if, [0, Max, fun is_greater_than_control/2])].
>>
>> 8> test:test_if(100000000).
>> [{7234000,done},{5718999,done}]
>>
>>
>> On Mon, Aug 27, 2012 at 2:00 PM, Andrzej Sliwa <andrzej.sliwa@REDACTED>wrote:
>>
>>> there is no difference in speed at all,
>>>
>>> > switch_signal({signal, _What, _From, _To}) ->
>>> >     true;
>>> > switch_signal({signal, _What, _To}) ->
>>> >     true;
>>> > switch_signal(_Else) ->
>>> >     false.
>>>
>>> is compiled internally to one function with case
>>> so code speed is equal
>>>
>>> there is only difference in readability.
>>>
>>> On Aug 27, 2012, at 10:56 PM, Jayson Barley <jayson.barley@REDACTED>
>>> wrote:
>>>
>>> > I am not sure I understand why we have them. For instance I can take
>>> the following code
>>> > is_greater_than(X, Y) ->
>>> >     if
>>> >         X>Y ->
>>> >             true;
>>> >         true -> % works as an 'else' branch
>>> >             false
>>> >     end.
>>> > And make it
>>> > is_true(true) ->
>>> >     true;
>>> > is_true(false) ->
>>> >     false.
>>> >
>>> > is_greater_than(X, Y) ->
>>> >     is_true(X>Y).
>>> > I can do the same thing with case statements
>>> > is_valid_signal(Signal) ->
>>> >     case Signal of
>>> >         {signal, _What, _From, _To} ->
>>> >             true;
>>> >         {signal, _What, _To} ->
>>> >             true;
>>> >         _Else ->
>>> >             false
>>> >     end.
>>> > Becomes
>>> > switch_signal({signal, _What, _From, _To}) ->
>>> >     true;
>>> > switch_signal({signal, _What, _To}) ->
>>> >     true;
>>> > switch_signal(_Else) ->
>>> >     false.
>>> >
>>> > is_valid_signal(Signal) ->
>>> >     switch_signal(Signal).
>>> >
>>> > I know that the control structures are a little bit faster, not much,
>>> but I find that the function form is more readable.
>>> > _______________________________________________
>>> > erlang-questions mailing list
>>> > erlang-questions@REDACTED
>>> > http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120827/ea62980e/attachment.htm>


More information about the erlang-questions mailing list