diff options
author | Anders Svensson <[email protected]> | 2017-04-28 08:59:31 +0200 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2017-06-13 13:50:06 +0200 |
commit | 4bfccba1943a21b1f723607f5b8e25773e48d98d (patch) | |
tree | cbfd8c49649bf6e2358dbbb5603f6073db07363e | |
parent | cfbe969341068623e609fd25c9c5f56b1fdc9458 (diff) | |
download | otp-4bfccba1943a21b1f723607f5b8e25773e48d98d.tar.gz otp-4bfccba1943a21b1f723607f5b8e25773e48d98d.tar.bz2 otp-4bfccba1943a21b1f723607f5b8e25773e48d98d.zip |
Avoid recreating records
This old construction is approximately two to four times slower from
best (no elements modified) to worst (all modified) case, with the new
construction having constant speed.
-rw-r--r-- | lib/diameter/src/base/diameter_lib.erl | 31 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_traffic.erl | 18 |
2 files changed, 14 insertions, 35 deletions
diff --git a/lib/diameter/src/base/diameter_lib.erl b/lib/diameter/src/base/diameter_lib.erl index 3928769b5e..58b9a29812 100644 --- a/lib/diameter/src/base/diameter_lib.erl +++ b/lib/diameter/src/base/diameter_lib.erl @@ -37,7 +37,6 @@ ipaddr/1, spawn_opts/2, wait/1, - fold_tuple/3, fold_n/3, for_n/2, log/4]). @@ -341,36 +340,6 @@ down(MRef) receive {'DOWN', MRef, process, _, _} = T -> T end. %% --------------------------------------------------------------------------- -%% # fold_tuple/3 -%% --------------------------------------------------------------------------- - --spec fold_tuple(N, T0, T) - -> tuple() - when N :: pos_integer(), - T0 :: tuple(), - T :: tuple() - | undefined. - -%% Replace fields in T0 by those of T starting at index N, unless the -%% new value is 'undefined'. -%% -%% eg. fold_tuple(2, Hdr, #diameter_header{end_to_end_id = 42}) - -fold_tuple(_, T, undefined) -> - T; - -fold_tuple(N, T0, T1) -> - {_, T} = lists:foldl(fun(V, {I,_} = IT) -> {I+1, ft(V, IT)} end, - {N, T0}, - lists:nthtail(N-1, tuple_to_list(T1))), - T. - -ft(undefined, {_, T}) -> - T; -ft(Value, {Idx, T}) -> - setelement(Idx, T, Value). - -%% --------------------------------------------------------------------------- %% # fold_n/3 %% --------------------------------------------------------------------------- diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl index 4a5df722e7..72fb92dcf9 100644 --- a/lib/diameter/src/base/diameter_traffic.erl +++ b/lib/diameter/src/base/diameter_traffic.erl @@ -1438,11 +1438,21 @@ make_retransmit_header(Hdr) -> Hdr#diameter_header{is_retransmitted = true}. %% fold_record/2 +%% +%% Replace elements in the first record by those in the second that +%% differ from undefined. + +fold_record(Rec0, undefined) -> + Rec0; +fold_record(Rec0, Rec) -> + list_to_tuple(fold(tuple_to_list(Rec0), tuple_to_list(Rec))). -fold_record(undefined, R) -> - R; -fold_record(Rec, R) -> - diameter_lib:fold_tuple(2, Rec, R). +fold([], []) -> + []; +fold([H | T0], [undefined | T]) -> + [H | fold(T0, T)]; +fold([_ | T0], [H | T]) -> + [H | fold(T0, T)]. %% send_R/6 |