[erlang-questions] What is the fastest way to check if a function is defined in a module?

Metin Akat akat.metin@REDACTED
Sun Mar 4 08:09:06 CET 2018


I haven't yet done rigorous testing with many processes, but what you are
suggesting is the slowest so far (at least by the most naive way of
measuring, while not under load) :

37> timer:tc(fun() -> lists:member({not_a_function, 1},
Module:module_info(exports)) end).
{514,false}
38> timer:tc(fun() -> try Module:not_a_function() catch error:undef ->
 not_defined end end).
{47,not_defined}
39> timer:tc(fun() -> erlang:function_exported(Module, not_a_function, 1)
end).
{8,false}


The reason I'm asking is because I saw this gen_server:try_dispatch/3
implementation and I am wondering what are the implications under heavy
load and concurrency.





On Sun, Mar 4, 2018 at 8:47 AM, Zachary Kessin <zkessin@REDACTED> wrote:

> I realize that there is a race condition in that code, if someone reloads
> the module at the wrong moment it could crash.
>
>
>
> Zach Kessin - CEO Finch Software
> I boost sales with retail chatbots for fashion and cosmetics
> +972 54 234 3956 <+972%2054-234-3956> / +44 203 734 9790
> <+44%2020%203734%209790> / +1 617 778 7213 <+1%20617-778-7213>
> Book a meeting with me <https://calendly.com/zkessin/chatbot>
>
> On Sun, Mar 4, 2018 at 8:37 AM, Zachary Kessin <zkessin@REDACTED> wrote:
>
>> You can use the function MODULE:module_info/1 something like
>> is_defined(MyFunc, Arity, MODULE)->
>>    Functions = MODULE:module_info(functions),
>>    lists:member({MyFunc,Arity}, Functions).
>>
>> Where MyFunc is an atom of course
>>
>> You could also expand that to a call_function_if_defined_with_default/N
>> but i will leave that to you
>>
>> Zach
>>
>>
>> Zach Kessin - CEO Finch Software
>> I boost sales with retail chatbots for fashion and cosmetics
>> +972 54 234 3956 <054-234-3956> / +44 203 734 9790
>> <+44%2020%203734%209790> / +1 617 778 7213 <+1%20617-778-7213>
>> Book a meeting with me <https://calendly.com/zkessin/chatbot>
>>
>> On Sat, Mar 3, 2018 at 9:42 PM, Metin Akat <akat.metin@REDACTED> wrote:
>>
>>> I'm looking into this code: https://github.com/erlan
>>> g/otp/blob/master/lib/stdlib/src/gen_server.erl#L631
>>>
>>> Seems like this try/catch clause is implemented with the idea that most
>>> of the time it will succeed, as the callback module will have implemented
>>> the corresponding callback function, so we will not have to go into the
>>> exception clause where it needs to call erlang:function_exported/2 one more
>>> time (presumably as an additional safeguard) which is more expensive than
>>> an optimistic try clause.
>>>
>>> I am writing something very similar, where such a check (is a function
>>> exported) will be performed by thousands/millions of processes on every
>>> message, but in my case... it's quite probable that most of the time this
>>> WILL raise the exception. In my case the function will be purely optional -
>>> if defined, it will return a value. If not, a default value will be used.
>>>
>>> So my question is, how bad is this? I will test, but I'm still
>>> interested if someone has any ideas (maybe do something completely
>>> different).
>>>
>>> Other possibilities are:
>>>
>>> - Actually make the callback compulsory. I don't want to do that, as the
>>> problem I'm solving with this project is "See, you don't have to implement
>>> this boilerplate every time any more"
>>>
>>> -  Put the option in application env where the user can configure it on
>>> startup.
>>>
>>>
>>>
>>> _______________________________________________
>>> 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/20180304/1053d9bb/attachment.htm>


More information about the erlang-questions mailing list