[erlang-questions] naive execution of guards
Kostis Sagonas
kostis@REDACTED
Tue Dec 12 18:26:30 CET 2006
Ulf Wiger (TN/EAB) wrote:
>
> I was curious to see whether the compiler would optimize away repeated
> use of the length/1 guard, e.g in the following code:
>
> check_arity(_, L, Min, Max)
> when is_list(L), length(L) =< Min, length(L) >= Max ->
> true;
>
> but compiling with erlc -S indicates that it doesn't:
>
> {function, check_arity, 4, 8}.
> {label,7}.
> {func_info,{atom,test},{atom,check_arity},4}.
> {label,8}.
> {bif,is_list,{f,9},[{x,1}],{x,4}}.
> {gc_bif,length,{f,9},5,[{x,1}],{x,5}}.
> {bif,'=<',{f,9},[{x,5},{x,2}],{x,5}}.
> {gc_bif,length,{f,9},6,[{x,1}],{x,6}}.
> {bif,'>=',{f,9},[{x,6},{x,3}],{x,6}}.
> {bif,'and',{f,9},[{x,5},{x,6}],{x,5}}.
> {bif,'and',{f,9},[{x,4},{x,5}],{x,4}}.
> {test,is_eq_exact,{f,9},[{x,4},{atom,true}]}.
> {move,{atom,true},{x,0}}.
> return.
>
> I guess there are two reasons for doing the optimization:
> - one less register to handle
> - length/1 is an O(N) bif
>
> I'm sure it's tricky, and I don't know if the above reasons are strong
> enough.
The 2nd reason IS strong enough.
Even some of the OTP code would benefit from it.
lib/compiler/src/sys_expand_pmod.erl: when length(As0) == 0;
length(As0) == 1 ->
lib/megaco/src/text/megaco_text_mini_parser.hrl: when length(Hex4) =<
4, length(Hex4) > 0 ->
lib/megaco/src/text/megaco_text_parser_prev3a.hrl: when length(Hex4) =<
4, length(Hex4) > 0 ->
lib/megaco/src/text/megaco_text_parser_prev3b.hrl: when length(Hex4) =<
4, length(Hex4) > 0 ->
lib/megaco/src/text/megaco_text_parser_prev3c.hrl: when length(Hex4) =<
4, length(Hex4) > 0 ->
lib/megaco/src/text/megaco_text_parser_v1.hrl: when length(Hex4) =< 4,
length(Hex4) > 0 ->
lib/megaco/src/text/megaco_text_parser_v2.hrl: when length(Hex4) =< 4,
length(Hex4) > 0 ->
lib/megaco/src/text/megaco_text_parser_v3.hrl: when length(Hex4) =< 4,
length(Hex4) > 0 ->
lib/megaco/test/megaco_test_msg_prev3b_lib.erl: when list(L), Min =<
length(L), length(L) =< Max ->
lib/megaco/test/megaco_test_msg_prev3c_lib.erl: when list(L), Min =<
length(L), length(L) =< Max ->
lib/megaco/test/megaco_test_msg_v2_lib.erl: when list(L), Min =<
length(L), length(L) =< Max ->
This should be optimized away by the compiler.
On a slightly unrelated topic: About a month ago, I suggested to OTP a
new guard (or possibly a family of guards, if open intervals are also
needed) tailored to integer ranges. Using these guards instead of writing:
... when Min =< N, N =< Max ->
would simply be written as:
... when in_range(Min, N, Max) ->
One immediate side effect, which admittedly I had not thought of when I
made the proposal, would be that when N was an expression such as e.g.
length(L), this expression would only appear once.
Kostis
More information about the erlang-questions
mailing list