<div dir="ltr">At the very least, one should exercise caution on some particular modules, and perhaps generally modules that have lots of type specs.<div><br></div><div>Interestingly, when fetching attributes from beam_lib, dialyzer-generated attributes are moved to a subgroup, so at least in OTP 20.0 code, attribute lists are no longer than 4.</div><div><br></div><div>Fetching via M:module_info/1, however, the list is flat, and can be quite long, mostly depending on the number of types. Looking again at OTP, but loading each module and fetching the attributes via M:module_info/1 (the example below lists all modules with at least 20 attributes):</div><div><br></div><div><div>19> lists:foldr(fun(D,Acc) -> filelib:fold_files(D, ".*", false, fun(F,A) -> M = list_to_atom(filename:basename(F,".beam")), try M:module_info(attributes) of As -> case length(As) of L when L >= 20 -> [{M,L}|A]; _ -> A end catch error:_ -> A end end, []) ++ Acc end, [], code:get_path()).</div><div>[{gen_fsm,20},</div><div> {erl_parse,208},</div><div> {xmerl_xpath_parse,45},</div><div> {xref_parser,34},</div><div> {snmpc_mib_gram,232},</div><div> {megaco_text_parser_v3,413},</div><div> {megaco_text_parser_v2,378},</div><div> {megaco_text_parser_v1,325},</div><div> {megaco_text_parser_prev3c,410},</div><div> {megaco_text_parser_prev3b,396},</div><div> {megaco_text_parser_prev3a,389},</div><div> {megaco_text_mini_parser,25},</div><div> {icparse,185},</div><div> {edoc_parser,94},</div><div> {diameter_dict_parser,76},</div><div> {cosNotification_Grammar,36},</div><div> {core_parse,224}]</div></div><div><br></div><div><br></div><div>BR,</div><div>Ulf W</div></div><div class="gmail_extra"><br><div class="gmail_quote">2017-09-28 8:56 GMT+02:00 Max Lapshin <span dir="ltr"><<a href="mailto:max.lapshin@gmail.com" target="_blank">max.lapshin@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi.<div><br></div><div>We have moved from plain text lager logging to our own event system that has main difference: we have limited amount of possible events that are compiled in code.</div><div><br></div><div>In known_events.erl I have:</div><div><br></div><div><br></div><div>-event({stream_started, info, ["stream started"]}).</div><div><br></div><div>and then I write in code:</div><div><br></div><div><br></div><div>events:stream_started([{media,<wbr>Name}]).</div><div><br></div><div>Later all this is printed (using lager formatting, it is cool).</div><div><br></div><div><br></div><div><br></div><div>So we are close to the problem. My code that was handling such:  events:stream_started was searching for predefined event via:  known_events:module_info(<wbr>attributes).</div><div><br></div><div>Suddenly eprof told that I need to look carefully at this place and I wrote parse_transform that takes all attributes from module AST and compiles them into code. Also I've generated function  known_events:find(Name) with all possible clauses.</div><div><br></div><div>On single core of my macbook I got 4000 times speedup.  100 000 of fetches known_events:all()  took about 8 seconds with module_info(attributes) and about 2 milliseconds with generated and compiled code.</div><div><br></div><div><br></div><div>So lesson from here is: try to avoid calling module_info(attributes) in innner loops. It may be suprisingly expensive.</div><div><br></div><div><br></div><div><br></div><div><br></div></div>
<br>______________________________<wbr>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div>