Erlang'e рдкрд░ рд╢реБрд░реБрдЖрддреА рдХреЗ рд▓рд┐рдП MapReduce

рдореИрдВ рдПрд░рд▓реИрдВрдЧ рдореЗрдВ рдЕрдкрдирд╛ рдбрд╛рдЗрд╡ рдЬрд╛рд░реА рд░рдЦрддрд╛ рд╣реВрдВред Erlang рдкрд░ рдирд┐рдЧрд░рд╛рдиреА рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдореБрд╢реНрдХрд┐рд▓ рдпреЛрдЬрдирд╛ рд╣реИред рдЕрдм рд╣рдо рдХреБрдЫ рдЙрддреНрдкрд╛рджреЛрдВ рдФрд░ рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдЬреИрд╕реЗ рдХреНрдпреВрдП рдХреЗ рд▓рд┐рдП рдПрдХ рдордВрдЪ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдПрдЬрд╝реНрдпреЛрд░ рдФрд░ рдЕрдореЗрдЬрд╝реЕрди рдИрд╕реА 2 рдмрд╛рджрд▓реЛрдВ рдореЗрдВ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд┐рдирд╛ рдХрдИ рдХреЛрд░ рдФрд░ рдорд╢реАрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЖрд╢рд╛рдЬрдирдХ рджрд┐рдЦрддреА рд╣реИред

рддреЛ, рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рд░рд▓ рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХрд╛ рдЙрджрд╛рд╣рд░рдг ~ 2000 рдлрд╝рд╛рдЗрд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИред рд╣рдореЗрдВ рдкреНрд░рдпреБрдХреНрдд рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, "getenv (...)" рдФрд░ "GetVariable (...)" (рдпрд╣ рд╣рдорд╛рд░рд╛ рдЖрд╡рд░рдг рд╣реИ) рд▓рд╛рдЗрдиреЛрдВ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдвреВрдВрдвреЗрдВ рдФрд░ рдЙрдирд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдлрд╛рдбрд╝ рджреЗрдВред

рдХрд╛рд░реНрдп рд╕реАрдзрд╛ рд╣реИ рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд╕реА ++ рдкреНрд░реЛрдЧреНрд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╕ рдпреВрдирд┐рдХреНрд╕ рдХреЛ "рдЦреЛрдЬ" рдХрд╣рддрд╛ рд╣реИ, рдЬреЛ рдорд╛рд╕реНрдХ рджреНрд╡рд╛рд░рд╛ рдлрд╛рдЗрд▓реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╕реВрдЪреА рдкрд░ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИред 2000 рдлрд╝рд╛рдЗрд▓реЛрдВ рдкрд░, рдпрд╣ рдПрдХ рдереНрд░реЗрдб рдореЗрдВ рдХреБрдЫ рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдЕрдм рдПрд░реНрд▓рд╛рдВрдЧред рдпрд╣рд╛рдБ рдореИрдВ рдЕрдиреБрдХреНрд░рдорд┐рдХ рдлрд╝рд╛рдЗрд▓ рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдШреБрдВрдШрд░рд╛рд▓реЗ рд╣рд▓рдЪрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред MapReduce рдмрд╕ рд╡рд┐рд╖рдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ - рдЖрдк рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╕рдорд╛рдирд╛рдВрддрд░ (рдореИрдк) рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд╛рдпрд╛ рдЧрдпрд╛ рдЪрд░ рдирд╛рдо рд╕рдВрдЪрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдВрддрд┐рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рднреА рдкреНрд░рд╛рдкреНрдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ (рд░рд┐рдбреНрдпреВрд╕), рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмрд╕ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореЗрд░рд╛ рдХреЛрдб " рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдПрд░рд▓рд╛рдВрдЧ" рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИ рдФрд░ рдЙрд╕реА рдкреБрд╕реНрддрдХ рд╕реЗ рдлреЙрдлреНрд╕ (рд╕рдорд╛рдирд╛рдВрддрд░ рдЙрдЪреНрдЪ рдХреНрд░рдо рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди) рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

-module(find_variables). -export([main/0, find_variables_in_file/2, process_found_variables/3]). -define(PATH, "/Projects/interesting_project"). -define(MASK, "\\..*(cpp|c)"). main() -> io:format("Creating list of files...~n", []), %     .   - % ,    . Files = filelib:fold_files(?PATH, ?MASK, true, fun(N, A) -> [N | A] end, []), io:format("Found ~b file(s)~n", [length(Files)]), F1 = fun find_variables_in_file/2, % Map F2 = fun process_found_variables/3, % Reduce %  MapReduce   benchmark,   % . benchmark(fun() -> L = phofs:mapreduce(F1, F2, [], Files), io:format("Found ~b variable(s)~n", [length(L)]) end, "MapReduce"). benchmark(Worker, Title) -> {T, _} = timer:tc(fun() -> Worker() end), io:format("~s: ~f sec(s)~n", [Title, T/1000000]). -define(REGEXP, "(getenv|GetVariable)\s*\\(\s*\"([^\"]+)\"\s*\\)"). % Map.   . find_variables_in_file(Pid, FileName) -> case file:open(FileName, [read]) of {ok, File} -> %    . {_, RE} = re:compile(?REGEXP), %       %      . CallBack = fun(Var) -> Pid ! {Var, 1} end, find_variable_in_file(File, RE, CallBack), file:close(File); {error, Reason} -> io:format("Unable to process '~s', ~p~n", [FileName, Reason]), exit(1) end. % Reduce.  .     %  MapReduce        % ,   .       % {VarName, 1}.      VarName  %  ,       . %      . process_found_variables(Key, Vals, A) -> [{Key, length(Vals)} | A]. %   . find_variable_in_file(File, RE, CallBack) -> case io:get_line(File, "") of eof -> void; Line -> scan_line_in_file(Line, RE, CallBack), find_variable_in_file(File, RE, CallBack) end. %        ( ), %      CallBack      % . scan_line_in_file(Line, RE, CallBack) -> case re:run(Line, RE) of {match, Captured} -> [_, _, {NameP, NameL}] = Captured, Name = string:substr(Line, NameP + 1, NameL), CallBack(Name); nomatch -> void end. 

рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдлреВрдл рдореЙрдбреНрдпреВрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ ред рдпрд╣ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╣реИ, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдирдЪрд┐рддреНрд░ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рд╣реИред

рдФрд░ рдореЗрдХрдлрд╛рдЗрд▓ рд╕рд┐рд░реНрдл рдорд╛рдорд▓реЗ рдореЗрдВ:

  target = find_variables all: erlc $(target).erl erlc phofs.erl erl -noshell -s $(target) main -s init stop clean: -rm *.beam *.dump 


рдмрдбрд╝рд╛ рд╣реЛ рдЧрдпрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдХрд╣рд╛, рдореЗрд░реА рдорд╢реАрди рдкрд░ "рдЦреЛрдЬ" рдХреЙрд▓ рдХреЗ рд╕рдордп рдХреЗ рд╕рд╛рде рдПрдХ C ++ рдкреНрд░реЛрдЧреНрд░рд╛рдо 1-2 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдЪрд▓рддрд╛ рд╣реИред Erlang'e рд╕рдВрд╕реНрдХрд░рдг ~ 20 рд╕реЗрдХрдВрдб рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдмреБрд░рд╛? рдпрд╣ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХреИрд╕реЗ рджрд┐рдЦрддреЗ рд╣реИрдВред рдпрджрд┐ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЕрдзрд┐рдХ рд▓рдВрдмрд╛ рд╣реЛрдЧрд╛ (рдЕрд░реНрдерд╛рдд, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдмрд┐рддрд╛рдПрдЧрд╛, рдФрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛), рддреЛ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЛ рдмрдврд╝рд╛рддреЗ рд╕рдордп рдХреМрди рд╕рд╛ рд╕рдорд╛рдзрд╛рди рдЕрдзрд┐рдХ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реЛрдЧрд╛ред

рдореИрдВ рдПрд░рд▓рд╛рдВрдЧ рдХреЗ рд▓рд┐рдП рдирдпрд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХреЛрдб рдХреА рдЖрд▓реЛрдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛ред

рд╕рдВрдмрдВрдзрд┐рдд рдкреЛрд╕реНрдЯ:

Source: https://habr.com/ru/post/In133750/


All Articles