diff options
author | José Valim <[email protected]> | 2015-02-19 11:46:14 +0100 |
---|---|---|
committer | José Valim <[email protected]> | 2015-02-19 11:46:14 +0100 |
commit | e8398cce2451f6323eb5d8cce4adf4d5b69bb098 (patch) | |
tree | b8f632c638b93f7430adb09b05a286722a94ec8e | |
parent | ef8b1e3e8c908379cec8376ed515c920682224f9 (diff) | |
download | otp-e8398cce2451f6323eb5d8cce4adf4d5b69bb098.tar.gz otp-e8398cce2451f6323eb5d8cce4adf4d5b69bb098.tar.bz2 otp-e8398cce2451f6323eb5d8cce4adf4d5b69bb098.zip |
Short-circuit common dict operations
Stop traversing all segments and buckets of empty
dictionaries by adding a clause that checks the
dictionary size.
This improved compilation of an erlang project from
7.5s to 5.5s seconds when trying out a sample
implementation of erl_lint that uses dicts.
-rw-r--r-- | lib/stdlib/src/dict.erl | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl index cf8fb3114a..5a9f63c5e2 100644 --- a/lib/stdlib/src/dict.erl +++ b/lib/stdlib/src/dict.erl @@ -417,6 +417,8 @@ on_bucket(F, T, Slot) -> %% could have implemented map and filter using fold but these are %% faster. We hope! +fold_dict(F, Acc, #dict{size=0}) when is_function(F, 3) -> + Acc; fold_dict(F, Acc, D) -> Segs = D#dict.segs, fold_segs(F, Acc, Segs, tuple_size(Segs)). @@ -434,6 +436,8 @@ fold_bucket(F, Acc, [?kv(Key,Val)|Bkt]) -> fold_bucket(F, F(Key, Val, Acc), Bkt); fold_bucket(F, Acc, []) when is_function(F, 3) -> Acc. +map_dict(F, #dict{size=0} = Dict) when is_function(F, 2) -> + Dict; map_dict(F, D) -> Segs0 = tuple_to_list(D#dict.segs), Segs1 = map_seg_list(F, Segs0), @@ -453,6 +457,8 @@ map_bucket(F, [?kv(Key,Val)|Bkt]) -> [?kv(Key,F(Key, Val))|map_bucket(F, Bkt)]; map_bucket(F, []) when is_function(F, 2) -> []. +filter_dict(F, #dict{size=0} = Dict) when is_function(F, 2) -> + Dict; filter_dict(F, D) -> Segs0 = tuple_to_list(D#dict.segs), {Segs1,Fc} = filter_seg_list(F, Segs0, [], 0), |