From 953f57e3a86f3b714a634177e32f630b56a05240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 10 Jan 2017 14:29:08 +0100 Subject: Remove comparisons of binary handling between R11B and R12B Shorten the text by removing superfluous details about how binary handling was different in R11B. --- system/doc/efficiency_guide/binaryhandling.xml | 81 +++++++++----------------- 1 file changed, 26 insertions(+), 55 deletions(-) (limited to 'system/doc/efficiency_guide') diff --git a/system/doc/efficiency_guide/binaryhandling.xml b/system/doc/efficiency_guide/binaryhandling.xml index 0295d18644..91fd9a7cd9 100644 --- a/system/doc/efficiency_guide/binaryhandling.xml +++ b/system/doc/efficiency_guide/binaryhandling.xml @@ -32,12 +32,9 @@ binaryhandling.xml -

In R12B, the most natural way to construct and match binaries is - significantly faster than in earlier releases.

+

Binaries can be efficiently built in the following way:

-

To construct a binary, you can simply write as follows:

- -

DO (in R12B) / REALLY DO NOT (in earlier releases)

+

DO

my_list_to_binary(List, <<>>). @@ -47,21 +44,13 @@ my_list_to_binary([H|T], Acc) -> my_list_to_binary([], Acc) -> Acc.]]> -

In releases before R12B, Acc is copied in every iteration. - In R12B, Acc is copied only in the first iteration and extra - space is allocated at the end of the copied binary. In the next iteration, - H is written into the extra space. When the extra space runs out, - the binary is reallocated with more extra space. The extra space allocated - (or reallocated) is twice the size of the - existing binary data, or 256, whichever is larger.

- -

The most natural way to match binaries is now the fastest:

+

Binaries can be efficiently matched like this:

-

DO (in R12B)

+

DO

>) -> [H|my_binary_to_list(T)]; -my_binary_to_list(<<>>) -> [].]]> +my_binary_to_list(<<>>) -> [].]]>
How Binaries are Implemented @@ -138,10 +127,7 @@ my_binary_to_list(<<>>) -> [].]]> pointer to the binary data. For each field that is matched out of a binary, the position in the match context is incremented.

-

In R11B, a match context was only used during a binary matching - operation.

- -

In R12B, the compiler tries to avoid generating code that +

The compiler tries to avoid generating code that creates a sub binary, only to shortly afterwards create a new match context and discard the sub binary. Instead of creating a sub binary, the match context is kept.

@@ -155,7 +141,7 @@ my_binary_to_list(<<>>) -> [].]]>
Constructing Binaries -

In R12B, appending to a binary or bitstring +

Appending to a binary or bitstring is specially optimized by the runtime system:

> %% Bin1 will be COPIED

Let us revisit the example in the beginning of the previous section:

-

DO (in R12B)

+

DO

>) -> [H|my_binary_to_list(T)]; @@ -304,15 +290,14 @@ my_binary_to_list(<<>>) -> [].]]> byte of the binary. 1 byte is matched out and the match context is updated to point to the second byte in the binary.

-

In R11B, at this point a - sub binary - would be created. In R12B, - the compiler sees that there is no point in creating a sub binary, - because there will soon be a call to a function (in this case, +

At this point it would make sense to create a + sub binary, + but in this particular example the compiler sees that + there will soon be a call to a function (in this case, to my_binary_to_list/1 itself) that immediately will create a new match context and discard the sub binary.

-

Therefore, in R12B, my_binary_to_list/1 calls itself +

Therefore my_binary_to_list/1 calls itself with the match context instead of with a sub binary. The instruction that initializes the matching operation basically does nothing when it sees that it was passed a match context instead of a binary.

@@ -321,34 +306,10 @@ my_binary_to_list(<<>>) -> [].]]>
the match context will simply be discarded (removed in the next garbage collection, as there is no longer any reference to it).

-

To summarize, my_binary_to_list/1 in R12B only needs to create - one match context and no sub binaries. In R11B, if the binary - contains N bytes, N+1 match contexts and N - sub binaries are created.

- -

In R11B, the fastest way to match binaries is as follows:

+

To summarize, my_binary_to_list/1 only needs to create + one match context and no sub binaries.

-

DO NOT (in R12B)

- - my_complicated_binary_to_list(Bin, 0). - -my_complicated_binary_to_list(Bin, Skip) -> - case Bin of - <<_:Skip/binary,Byte,_/binary>> -> - [Byte|my_complicated_binary_to_list(Bin, Skip+1)]; - <<_:Skip/binary>> -> - [] - end.]]> - -

This function cleverly avoids building sub binaries, but it cannot - avoid building a match context in each recursion step. - Therefore, in both R11B and R12B, - my_complicated_binary_to_list/1 builds N+1 match - contexts. (In a future Erlang/OTP release, the compiler might be able - to generate code that reuses the match context.)

- -

Returning to my_binary_to_list/1, notice that the match context +

Notice that the match context in my_binary_to_list/1 was discarded when the entire binary had been traversed. What happens if the iteration stops before it has reached the end of the binary? Will the optimization still work?

@@ -544,5 +505,15 @@ count3(<<>>, Count) -> Count.]]> not matched out.

+ +
+ Historical Note + +

Binary handling was significantly improved in R12B. Because + code that was efficient in R11B might not be efficient in R12B, + and vice versa, earlier revisions of this Efficiency Guide contained + some information about binary handling in R11B.

+
+ -- cgit v1.2.3