What is "cheaper"?

Raimo Niskanen raimo+erlang-questions@REDACTED
Fri Mar 26 07:50:03 CET 2021

On Thu, Mar 25, 2021 at 08:06:11PM +0200, Valentin Micic wrote:
> > On 25 Mar 2021, at 16:26, Maria Scott <maria-12648430@REDACTED> wrote:
> > 
> > Hi,
> > 
> > not sure about cheap, but...
> > 
> >> But, Culpa Mea — I should have formulated my question a bit better.
> >> Thus, let me take another stab at it: what would be more efficient, canceling the timer (and thus avoiding generation of the message), or letting the send_after/3 generating (and runtime delivering) the message?
> >> The answer should be considered relative to the "event ordering" process — will it spend more time canceling the message, or removing generated message from its queue)?
> > 
> > ... it may happen that the timer expires and sends the message just before you cancel it. The message will then pollute your message queue. As such, you should react on the return of cancel_timer/1, if it returns false you may want to flush out that message.
> > 
> > But on another note, erlang:cancel_timer/1 is synonymous to erlang:cancel_timer/2 with options {async, false} and {info, true}, which results in a blocking operation that will wait for the cancellation to really "happen". You may look into option {async, true}, which will immediately return ok and not block the calling process. You will still have to take care of the possible message that may have been sent just before you cancelled the timer.
> > 
> > Kind regards,
> > Maria Scott
> Thank you, Maria
> All things considered, it appears to be “cheaper" not to cancel the timer (and thus generated event) when the timer values for are reasonably small (e.g. a few seconds), but desirable to do so (as Jasper suggested), when values for the timer are relatively high (in order to provide for a better memory utilisation used by erlang:send_after/3 scheduler). 

I am certainly not certain... ;-)

A cancel_timer/1 for a timer that is bound for the process that calls
cancel_timer/1 is comparatively efficient.  It is when you cancel some
other process' timer it gets harder to handle.

Processing a message always takes some time, but if you always receive any
message without matching, then ditching a bogus time-out message is not
much work.  But the message still has to be generated and received.

So the standard pattern
  case erlang:cancel_timer(Tref) of
      false -> receive {timeout, Tref, _} -> ok end;
      _ -> ok
will, when cancelling your own timer be fairly lightweight regarding locks,
and mostly return the time left, so no receive is done.

My guess is that that normal case is cheap.  But if it is cheaper then
cancelling with {async,true} and ditching a time-out message in a receive
any loop you already have?   Hard to guess...

> Kind regards
> V/


/ Raimo Niskanen, Erlang/OTP, Ericsson AB

More information about the erlang-questions mailing list