[erlang-questions] binary optimization
Richard Carlsson
richardc@REDACTED
Sat Jul 18 14:54:28 CEST 2009
Joel Reymont wrote:
> What about this one? I'm calling session:subscribe/2 and that's known at
> compile time.
>
> src/transport.erl:98: Warning: NOT OPTIMIZED: sub binary used by
> session:subscribe/2
>
> 98: handle_info({tcp, Sock, <<_:96, ?SUBSCRIBE, Topic/binary>>},
> State) ->
> inet:setopts(Sock, [{active, once}]),
> session:subscribe(State#state.session, Topic),
> {noreply, State};
Well, no. Because you could dynamically replace the session module at
any time, so the compiler can't really make any assumptions about what
that function does (or will do after a future code upgrade).
You should probably not dwell too much on these warnings. They are
hints to allow you to optimize what you're doing with binaries,
but those optimizations can only happen in particular (though
important) circumstances. Your code does not seem to be an example
of those circumstances.
Though I haven't taken a closer look at these binary optimizations
myself, this is my understanding of it:
1) When you match out a subsection of a binary, the system may use a
small (a few words) representation of this subsection in the form
of a "sub-binary", which is simply a reference that says "I'm this
part of that guy over there". The sub-binary will be allocated on
the heap, just like any other data, and to the user it looks like
you made a copy of a part of the original binary. If the part is
quite small, the system might choose to copy the data to a new
proper binary instead of making a sub-binary. So far so good.
2) Depending on what you're going to do with that sub-binary, it might
be a waste of time to create it on the heap, if it's not going to
live for very long (and in particular if this is in the middle of
a loop over a binary). The "delayed sub-binary optimization" is
when the compiler decides to keep the sub-binary info in registers
or on the stack instead. If the functions makes a tail-recursive
call to itself with the sub-binary as one of the arguments, the
compiler can detect that it still doesn't need to actually create
a heap object, but just loop with the info still kept in registers
and/or on the stack.
3) This means that if what you're doing is to put the sub-binary in a
data structure, this optimization is off. The same goes if you are
passing it to an unknown function (or perhaps even to _any_ other
function except for tail calls to the current function; this is
where Mikael and I aren't sure).
4) Unless you _are_ doing some kind of loop over the contents of a
binary, these optimizations are rather negligible, but when you
_do_ need to traverse a binary, they can give a good speedup.
/Richard
More information about the erlang-questions
mailing list