Conditional iolist_to_binary?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Conditional iolist_to_binary?

Loïc Hoguin-3
Hello,

I seem to be getting a small but noticeable performance improvement when
I change the following:

Value = iolist_to_binary(Value0)

Into the following:

Value = if
     is_binary(Value0) -> Value0;
     true -> iolist_to_binary(Value0)
end

At least when the input data is mostly binaries. Anyone else seeing this?

The only difference between is_binary and iolist_to_binary seems to be
that is_binary calls is_binary/binary_bitsize on the same if expression
while iolist_to_binary has two if statements.

What gives?

Cheers,

--
Loïc Hoguin
https://ninenines.eu
Reply | Threaded
Open this post in threaded view
|

Re: Conditional iolist_to_binary?

Dániel Szoboszlay
Hi,

My guess the reason is that the iolist_to_binary(Value0) call compiles into a call_ext, while the is_binary(Value0) to a test assembly instruction. This means all live X registers have to be saved to the heap (and restored later) in the first case. Inlining the is_binary check can save you that (and a somewhat expensive external function call) when Value0 is already a binary. But how much a difference this is depends on how many live X registers you have at that point. Maybe try compiling the actual module with erlc -S and compare the generated assembly code with and without the if statement?

Cheers,
Daniel

On Fri, 27 Dec 2019 at 11:07, Loïc Hoguin <[hidden email]> wrote:
Hello,

I seem to be getting a small but noticeable performance improvement when
I change the following:

Value = iolist_to_binary(Value0)

Into the following:

Value = if
     is_binary(Value0) -> Value0;
     true -> iolist_to_binary(Value0)
end

At least when the input data is mostly binaries. Anyone else seeing this?

The only difference between is_binary and iolist_to_binary seems to be
that is_binary calls is_binary/binary_bitsize on the same if expression
while iolist_to_binary has two if statements.

What gives?

Cheers,

--
Loïc Hoguin
https://ninenines.eu
Reply | Threaded
Open this post in threaded view
|

Re: Conditional iolist_to_binary?

Loïc Hoguin-3
That was it, thanks. And more importantly thanks for the explanations!

Interesting...

On 27/12/2019 22:54, Dániel Szoboszlay wrote:

> Hi,
>
> My guess the reason is that the iolist_to_binary(Value0) call compiles
> into a call_ext, while the is_binary(Value0) to a test assembly
> instruction. This means all live X registers have to be saved to the
> heap (and restored later) in the first case. Inlining the is_binary
> check can save you that (and a somewhat expensive external function
> call) when Value0 is already a binary. But how much a difference this is
> depends on how many live X registers you have at that point. Maybe try
> compiling the actual module with erlc -S and compare the generated
> assembly code with and without the if statement?
>
> Cheers,
> Daniel
>
> On Fri, 27 Dec 2019 at 11:07, Loïc Hoguin <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hello,
>
>     I seem to be getting a small but noticeable performance improvement
>     when
>     I change the following:
>
>     Value = iolist_to_binary(Value0)
>
>     Into the following:
>
>     Value = if
>           is_binary(Value0) -> Value0;
>           true -> iolist_to_binary(Value0)
>     end
>
>     At least when the input data is mostly binaries. Anyone else seeing
>     this?
>
>     The only difference between is_binary and iolist_to_binary seems to be
>     that is_binary calls is_binary/binary_bitsize on the same if expression
>     while iolist_to_binary has two if statements.
>
>     What gives?
>
>     Cheers,
>
>     --
>     Loïc Hoguin
>     https://ninenines.eu
>

--
Loïc Hoguin
https://ninenines.eu