[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 很长的情况下优化会更明显.


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

查看所有标签

猜你喜欢:

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

Web协议与实践

Web协议与实践

克里希纳穆尔蒂 (KrishnamurthyBalachander) / 范群波 / 科学出版社 / 2003-7 / 46.0

本书全面论述了传输Web内容的系统和协议,重点讲述了Web中业已成熟和稳定的技术,如TCP/IP协议及DNS技术、HITP/1.0的设计及其与TCP之间的交互;深入阐述了Web高速缓存技术和多媒体流播技术的最新技术动态;分析了Apache Web服务器和Squid代理;还探讨了通信量的分析和测量技术。书中使用了大量示例、技术发展水平报告以及案例分析来阐述Web的工作原理和各个组件之间的交互。本书是......一起来看看 《Web协议与实践》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器