aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_codec.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2017-07-29 16:53:18 +0200
committerAnders Svensson <[email protected]>2017-08-03 17:17:37 +0200
commit1a2c87f0035849fc5a24bff5dd36796500d1f451 (patch)
treeb9101ec9035474083ce13c4a7a70b6e2a1943c5b /lib/diameter/src/base/diameter_codec.erl
parent96cd627acfde682875149effda4611dc778622fd (diff)
downloadotp-1a2c87f0035849fc5a24bff5dd36796500d1f451.tar.gz
otp-1a2c87f0035849fc5a24bff5dd36796500d1f451.tar.bz2
otp-1a2c87f0035849fc5a24bff5dd36796500d1f451.zip
Optimize sub-binaries
With ERL_COMPILER_OPTIONS=bin_opt_info, before: base/diameter_codec.erl:508: Warning: NOT OPTIMIZED: the binary matching instruction that follows in the same function have problems that prevent delayed sub binary optimization (probably indicated by INFO warnings) And after: base/diameter_codec.erl:508: Warning: OPTIMIZED: creation of sub binary delayed This has a surprisingly large impact on the performance of diameter_codec:collect_avps/2: about 15% faster in one testcase on a RAR with 7 AVPs.
Diffstat (limited to 'lib/diameter/src/base/diameter_codec.erl')
-rw-r--r--lib/diameter/src/base/diameter_codec.erl51
1 files changed, 28 insertions, 23 deletions
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index 81c21fb8f2..c171ea9dca 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -506,20 +506,33 @@ collect_avps(<<_:20/binary, Avps/binary>>) ->
%% +-+-+-+-+-+-+-+-+
collect(<<Code:32, V:1, M:1, P:1, _:5, Len:24, I:V/unit:32, Rest/binary>>) ->
- Vid = if 1 == V -> I; 0 == V -> undefined end,
- DataLen = Len - 8 - V*4, %% Might be negative, which ensures
- Pad = ?PAD(Len), %% failure of the match below.
- MB = 1 == M,
- PB = 1 == P,
-
- case Rest of
- <<Data:DataLen/binary, _:Pad/binary, T/binary>> ->
+ collect(Rest,
+ Code,
+ if 1 == V -> I; 0 == V -> undefined end,
+ Len - 8 - V*4, %% Might be negative, which ensures
+ ?PAD(Len), %% failure of the match below.
+ 1 == M,
+ 1 == P);
+
+collect(<<>>) ->
+ [];
+
+%% Header is truncated. pack_avp/1 will pad this at encode if sent in
+%% a Failed-AVP.
+collect(Bin) ->
+ [#diameter_avp{data = {5014, Bin}}].
+
+%% collect/7
+
+collect(Bin, Code, Vid, DataLen, Pad, M, P) ->
+ case Bin of
+ <<Data:DataLen/binary, _:Pad/binary, Rest/binary>> ->
Avp = #diameter_avp{code = Code,
vendor_id = Vid,
- is_mandatory = MB,
- need_encryption = PB,
+ is_mandatory = M,
+ need_encryption = P,
data = Data},
- [Avp | collect(T)];
+ [Avp | collect(Rest)];
_ ->
%% Length in header points past the end of the message, or
%% doesn't span the header. Note that an length error can
@@ -529,18 +542,10 @@ collect(<<Code:32, V:1, M:1, P:1, _:5, Len:24, I:V/unit:32, Rest/binary>>) ->
%% know the types of the AVPs being extracted.
[#diameter_avp{code = Code,
vendor_id = Vid,
- is_mandatory = MB,
- need_encryption = PB,
- data = {5014, Rest}}]
- end;
-
-collect(<<>>) ->
- [];
-
-%% Header is truncated. pack_avp/1 will pad this at encode if sent in
-%% a Failed-AVP.
-collect(Bin) ->
- [#diameter_avp{data = {5014, Bin}}].
+ is_mandatory = M,
+ need_encryption = P,
+ data = {5014, Bin}}]
+ end.
%% 3588:
%%