# [erlang-questions] dialyzer orelse filter slowness

Tobias Lindahl <>
Thu Mar 26 09:53:04 CET 2009

```
> Hello,
>
> I've got a module that dialyzer takes more than 15 minutes to analyze,
> and I've narrowed down the cause to a fairly long orelse expression
> that is being used as a filter in a list comprehension.  If I replace
> the orelse expression with a function call and make each individual
> test it's own function, dialyzer is much happier and completes within
> seconds.  Does anyone have an explanation for why dialyzer might take
> so long on the orelse's when used as a filter?

orelse is expanded by the compiler to a case expression, so basically
your long line of orelses becomes deeply nested cases.

Dialyzer analyses each function (or rather each strongly connected
component of functions) in isolation, and abstracts the types at the
function borders, so when you break your tests into different functions
it is just a matter of analyzing a bunch of very simple functions which
explains why Dialyzer is fast there.

In contrast, the function with the deeply nested case is analyzed
without abstraction, and the relatively complicated control structure
makes the analysis pretty slow.

I hope that this will be faster in R13 because of an improvement in the
compilation of orelses.

Tobias

>
> Here's a bit of code that demonstrates the issue, which I've seen
> using both R11B and R12B.
>
> --
> -module (test).
> -export ([ foo/1 ]).
>
> -ifdef (USE_ORELSE).
> -define (bar (F),
>          ((F) =:= a orelse
>           (F) =:= b orelse
>           (F) =:= c orelse
>           (F) =:= d orelse
>           (F) =:= e orelse
>           (F) =:= f orelse
>           (F) =:= g orelse
>           (F) =:= h orelse
>           (F) =:= i orelse
>           (F) =:= j orelse
>           (F) =:= k)).
> -else.
> -define (bar, bar_f).
>           bar_f (a) -> true;
>           bar_f (b) -> true;
>           bar_f (c) -> true;
>           bar_f (d) -> true;
>           bar_f (e) -> true;
>           bar_f (f) -> true;
>           bar_f (g) -> true;
>           bar_f (h) -> true;
>           bar_f (i) -> true;
>           bar_f (j) -> true;
>           bar_f (k) -> true;
>           bar_f (_) -> false.
> -endif.
>
> foo (List) ->
>   [ F || F <- List, ?bar (F)].
> --
>
>
> % dialyzer --no_check_plt --src -c .
>   Proceeding with analysis... done in 0m0.23s
> done (passed successfully)
>
> % dialyzer -DUSE_ORELSE=1 --no_check_plt --src -c .
>   Proceeding with analysis... done in 0m32.24s
> done (passed successfully)
>
> Thanks!
> - n
> _______________________________________________
> erlang-questions mailing list
>
> http://www.erlang.org/mailman/listinfo/erlang-questions

```