[erlang PR猎人] Optimize v3_kernel for thousands of clauses #2165

栏目: Erlang · 发布时间: 6年前

内容简介:本 PR 中, Jose Valim 优化了以下这一段逻辑被删除了, 这里对 Cs 有一次遍历:它首先对 Cs 中所有的 clause 做了

本 PR 中, Jose Valim 优化了 v3_kernel 中对于 match clauses 的处理函数 match_con/4 , 在有上千个clauses 的情况下, 编译速度有 10% 的提升.

以下这一段逻辑被删除了, 这里对 Cs 有一次遍历:

%% old
match_con(Us, Cs0, Def, St) ->
    %% Expand literals at the top level.
    Cs = [expand_pat_lit_clause(C) || C <- Cs0],
    match_con_1(Us, Cs, Def, St).
复制代码

它首先对 Cs 中所有的 clause 做了 expand_pat_lit_clause/1 操作. 之后 match_con_1/4 函数体中的逻辑, 与新代码中有些许不同:

%% old
match_con_1([U|_Us] = L, Cs, Def, St0) ->
    %% Extract clauses for different constructors (types).
    %%ok = io:format("match_con ~p~n", [Cs]),
    Ttcs0 = select_types([k_binary], Cs) ++ select_bin_con(Cs) ++
        select_types([k_cons,k_tuple,k_map,k_atom,k_float,
                      k_int,k_nil], Cs),
    Ttcs = opt_single_valued(Ttcs0),

%% new
match_con([U|_Us] = L, Cs, Def, St0) ->
    Ttcs0 = select_types(Cs, [], [], [], [], [], [], [], [], []),
    Ttcs1 = [{T, Types} || {T, [_ | _] = Types} <- Ttcs0],
    Ttcs = opt_single_valued(Ttcs1),
复制代码

注意到, 在执行最后一行之前, 都通过 select_types 函数对 Cs 做了处理. 在old 代码中, 对于 k_binary type, 要遍历一次Cs; 对于 select_bin_con , 又要遍历一次 Cs; 对于其它 types, 还要遍历一次 Cs. 而在new 代码中, 只遍历了一次 Cs. select_types 函数是这个 PR 里改动最大的地方, 让我们来看一下:

%% old
select_types(Types, Cs) ->
    [{T,Tcs} || T <- Types, begin Tcs = select(T, Cs), Tcs =/= [] end].

%% select(Con, [Clause]) -> [Clause].

select(T, Cs) -> [ C || C <- Cs, clause_con(C) =:= T ].


%% new
select_types([NoExpC | Cs], Bin, BinCon, Cons, Tuple, Map, Atom, Float, Int, Nil) ->
    C = expand_pat_lit_clause(NoExpC),
    case clause_con(C) of
	k_binary ->
	    select_types(Cs, [C |Bin], BinCon, Cons, Tuple, Map, Atom, Float, Int, Nil);
	k_bin_seg ->
	    select_types(Cs, Bin, [C | BinCon], Cons, Tuple, Map, Atom, Float, Int, Nil);
	k_bin_end ->
	    select_types(Cs, Bin, [C | BinCon], Cons, Tuple, Map, Atom, Float, Int, Nil);
	k_cons ->
	    select_types(Cs, Bin, BinCon, [C | Cons], Tuple, Map, Atom, Float, Int, Nil);
	k_tuple ->
	    select_types(Cs, Bin, BinCon, Cons, [C | Tuple], Map, Atom, Float, Int, Nil);
	k_map ->
	    select_types(Cs, Bin, BinCon, Cons, Tuple, [C | Map], Atom, Float, Int, Nil);
	k_atom ->
	    select_types(Cs, Bin, BinCon, Cons, Tuple, Map, [C | Atom], Float, Int, Nil);
	k_float ->
	    select_types(Cs, Bin, BinCon, Cons, Tuple, Map, Atom, [C | Float], Int, Nil);
	k_int ->
	    select_types(Cs, Bin, BinCon, Cons, Tuple, Map, Atom, Float, [C | Int], Nil);
	k_nil ->
	    select_types(Cs, Bin, BinCon, Cons, Tuple, Map, Atom, Float, Int, [C | Nil])
    end;
select_types([], Bin, BinCon, Cons, Tuple, Map, Atom, Float, Int, Nil) ->
    [{k_binary, reverse(Bin)}] ++ handle_bin_con(reverse(BinCon)) ++
	[
	    {k_cons, reverse(Cons)},
	    {k_tuple, reverse(Tuple)},
	    {k_map, reverse(Map)},
	    {k_atom, reverse(Atom)},
	    {k_float, reverse(Float)},
	    {k_int, reverse(Int)},
	    {k_nil, reverse(Nil)}
	].
复制代码

注意到尽管新代码里只需要遍历一次 Cs, 但最后的结果还是要每个小 list 都做一次反转的. 所以, 此 PR 的性能优化点是在把对于一个 list 的四次遍历变为了一次遍历, 在 list 很长的情况下优化会更明显.


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro CSS and HTML Design Patterns

Pro CSS and HTML Design Patterns

Michael Bowers / Apress / April 23, 2007 / $44.99

Design patterns have been used with great success in software programming. They improve productivity, creativity, and efficiency in web design and development, and they reduce code bloat and complexit......一起来看看 《Pro CSS and HTML Design Patterns》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具