瀏覽代碼

ft: 完善代码

master
SisMaker 4 年之前
父節點
當前提交
f7a12cc4ea
共有 7 個文件被更改,包括 423 次插入107 次删除
  1. +1
    -1
      README.md
  2. +9
    -1
      rebar.config
  3. +113
    -39
      src/eAcs.erl
  4. +79
    -66
      src/genAcs.erl
  5. +0
    -0
      src/test/SWord.txt
  6. +216
    -0
      src/test/acTc.erl
  7. +5
    -0
      src/test/test.txt

+ 1
- 1
README.md 查看文件

@ -5,5 +5,5 @@ An OTP library
Build
-----
$ rebar3 escriptize
$ rebar3 compile

+ 9
- 1
rebar.config 查看文件

@ -1,4 +1,12 @@
{erl_opts, [no_debug_info]}.
{deps, [
{eFmt, {git, "http://47.108.26.175:53000/SisMaker/eFmt.git", {branch, "master"}}}
]}.
]}.
%% escript
{escript_main_app, eAcs}. % specify which app is the escript app
{escript_name, genAcs}. % name of final generated escript
{escript_emu_args, "%%! -escript main genAcs\n"}. % emulator args
%%{escript_shebang, "#!/usr/bin/env escript\n"}. % executable line
%%{escript_comment, "%%\n"}. % comment at top of escript file

+ 113
- 39
src/eAcs.erl 查看文件

@ -1,54 +1,128 @@
-module(eAcs).
-export([
match/2
matchSw/1 %%
, isHasSw/1 %%
, replaceSw/1 %%
]).
%% State is used to locate node, every node is a map
%% state 0 is the root node
%%
%% Goto: State -> Map{Char -> State}
%% Ouput: State -> String
%% Failure: State -> State
%% Goto: State -> #{Word -> State}
%% failOut: State -> {FailState, BinStr}
%% *************************************** matchSw start ***************************************************************
-spec matchSw(BinStr :: binary()) -> [{StartIndex :: integer(), EndIndex :: integer(), Pattern :: binary()}].
matchSw(BinStr) ->
doMatch(BinStr, 0, _Index = 1, _MatchList = []).
%% try to find patterns in string
%% the match index starts from 1
%% @return [{StartIndex, EndIndex, Pattern},...]
match(String, {Goto, Failure, Output}) ->
do_match(String, 0, {Goto, Failure, Output}, _Index = 1, _MatchList = []).
do_match([], _, _, _Index, MatchList) ->
doMatch(<<>>, _, _Index, MatchList) ->
MatchList;
do_match([Char|Tail], State, {Goto, Failure, Output}, Index, MatchList) ->
{NewState, NewMatchList} = do_match_inner(Char, State, {Goto, Failure, Output}, Index, MatchList),
do_match(Tail, NewState, {Goto, Failure, Output}, Index + 1, NewMatchList).
%% {NewState, NewMatchList}
do_match_inner(Char, State, {Goto, Failure, Output}, Index, MatchList) ->
#{State := Node} = Goto,
case maps:find(Char, Node) of
error ->
case State =:= 0 of
true ->
doMatch(<<Word/utf8, Tail/binary>>, State, Index, MatchList) ->
{NewState, NewMatchList} = matchInner(Word, State, Index, MatchList),
doMatch(Tail, NewState, Index + 1, NewMatchList).
matchInner(Word, State, Index, MatchList) ->
Node = acsTrees:goto(State),
case Node of
undefined ->
case State of
0 ->
{State, MatchList};
false ->
NextState = maps:get(State, Failure, 0),
do_match_inner(Char, NextState, {Goto, Failure, Output}, Index, MatchList)
_ ->
{NextState, _} = acsTrees:failOut(State),
matchInner(Word, NextState, Index, MatchList)
end;
{ok, NextState} ->
NewMatchList = get_output(NextState, {Goto, Failure, Output}, Index, MatchList),
{NextState, NewMatchList}
_ ->
case Node of
#{Word := NextState} ->
NewMatchList = getOutput(NextState, Index, MatchList),
{NextState, NewMatchList};
_ ->
case State of
0 ->
{State, MatchList};
_ ->
{NextState, _} = acsTrees:failOut(State),
matchInner(Word, NextState, Index, MatchList)
end
end
end.
get_output(0, _, _Index, MatchList) ->
getOutput(0, _Index, MatchList) ->
MatchList;
get_output(State, {Goto, Failure, Output}, Index, MatchList) ->
NewMatchList = case maps:find(State, Output) of
error -> MatchList;
{ok, Pattern} -> [{Index-length(Pattern) + 1, Index, Pattern} | MatchList]
end,
FailureState = maps:get(State, Failure, 0),
get_output(FailureState, {Goto, Failure, Output}, Index, NewMatchList).
getOutput(State, Index, MatchList) ->
{FailState, Pattern} = acsTrees:failOut(State),
case Pattern of
undefined ->
getOutput(FailState, Index, MatchList);
_ ->
NewMatchList = [{Index - patternSize(Pattern, 0) + 1, Index, Pattern} | MatchList],
getOutput(FailState, Index, NewMatchList)
end.
%% *************************************** matchSw end ***************************************************************
%% *************************************** isHasSw start ***************************************************************
-spec isHasSw(BinStr :: binary()) -> boolean().
isHasSw(BinStr) ->
doMatch(BinStr, 0).
doMatch(<<>>, _) ->
false;
doMatch(<<Word/utf8, Tail/binary>>, State) ->
case matchInner(Word, State) of
true ->
true;
NewState ->
doMatch(Tail, NewState)
end.
matchInner(Word, State) ->
Node = acsTrees:goto(State),
case Node of
undefined ->
case State of
0 ->
State;
_ ->
{NextState, _} = acsTrees:failOut(State),
matchInner(Word, NextState)
end;
_ ->
case Node of
#{Word := NextState} ->
case getOutput(NextState) of
false ->
NextState;
_ ->
true
end;
_ ->
case State of
0 ->
State;
_ ->
{NextState, _} = acsTrees:failOut(State),
matchInner(Word, NextState)
end
end
end.
getOutput(0) ->
false;
getOutput(State) ->
{FailState, Pattern} = acsTrees:failOut(State),
case Pattern of
undefined ->
false;
_ ->
getOutput(FailState)
end.
%% *************************************** matchSw end ***************************************************************
%% *************************************** replaceSw start *************************************************************
replaceSw(_BinStr) ->
ok.
%% *************************************** replaceSw end *************************************************************
patternSize(<<>>, Cnt) ->
Cnt;
patternSize(<<_Word/utf8, Left/binary>>, Cnt) ->
patternSize(Left, Cnt + 1).

+ 79
- 66
src/genAcs.erl 查看文件

@ -6,24 +6,28 @@
]).
main(Args) ->
[SNFile, WriteDir] = Args,
case file:open(SNFile, [read, raw, binary, {read_ahead, 65536}, {'encoding', 'utf8'}]) of
[SWFile, WriteDir] = Args,
case file:open(SWFile, [read, raw, binary, {read_ahead, 65536}, {encoding, utf8}]) of
{ok, IoDevice} ->
{Goto, Output} = dealEveryLine(IoDevice, _Goto=#{0 => #{}}, _Output=#{}, _State=0),
{Goto, Output} = dealEveryLine(IoDevice, _Goto = #{0 => #{}}, _Output = #{}, _State = 0),
Failure = genFailure(Goto),
genErl(WriteDir, Goto, Failure, Output);
_Err ->
io:format("genAcs open the file:~p error ~p~n", [SNFile, _Err])
io:format("genAcs open the file:~p error ~p~n", [SWFile, _Err])
end.
dealEveryLine(IoDevice, Goto, Output, MaxState) ->
case file:read_line(IoDevice) of
{ok, DataStr} ->
%% io:format("IMY*********** ~w ~n", [DataStr]),
BinStr = binary:part(DataStr, 0, byte_size(DataStr) - 1),
{NewGoto, NewState, NewMaxState} = addPattern(BinStr, Goto, 0, MaxState),
NewOutput = Output#{NewState => BinStr},
dealEveryLine(IoDevice, NewGoto, NewOutput, NewMaxState);
case BinStr =/= <<>> of
true ->
{NewGoto, NewState, NewMaxState} = addPattern(BinStr, Goto, 0, MaxState),
NewOutput = Output#{NewState => BinStr},
dealEveryLine(IoDevice, NewGoto, NewOutput, NewMaxState);
_ ->
dealEveryLine(IoDevice, Goto, Output, MaxState)
end;
eof ->
{Goto, Output};
_Err ->
@ -33,15 +37,20 @@ dealEveryLine(IoDevice, Goto, Output, MaxState) ->
%% ac搜索树
genTree(BinStrList) ->
%% goto and output table
{Goto, Output} = genGotoOutput(BinStrList, _Goto=#{0 => #{}}, _Output=#{}, _State=0),
{Goto, Output} = genGotoOutput(BinStrList, _Goto = #{0 => #{}}, _Output = #{}, _State = 0),
%% failure table
Failure = genFailure(Goto),
{Goto, Failure, Output}.
genGotoOutput([BinStr |Tail], Goto, Output, MaxState) ->
{NewGoto, NewState, NewMaxState} = addPattern(BinStr, Goto, 0, MaxState),
NewOutput = Output#{NewState => BinStr},
genGotoOutput(Tail, NewGoto, NewOutput, NewMaxState);
genGotoOutput([BinStr | Tail], Goto, Output, MaxState) ->
case BinStr =/= <<>> of
true ->
{NewGoto, NewState, NewMaxState} = addPattern(BinStr, Goto, 0, MaxState),
NewOutput = Output#{NewState => BinStr},
genGotoOutput(Tail, NewGoto, NewOutput, NewMaxState);
_ ->
genGotoOutput(Tail, Goto, Output, MaxState)
end;
genGotoOutput([], Goto, Output, _MaxState) ->
{Goto, Output}.
@ -60,55 +69,55 @@ addPattern(<<>>, Goto, State, MaxState) ->
genFailure(#{0 := Node} = Goto) ->
States = maps:values(Node),
genFailure(States, Goto, _Failure=#{}).
genFailure(States, Goto, _Failure = #{}).
%% failure with bfs搜索
genFailure([], _Goto, Failure) ->
Failure;
genFailure([State|Tail], Goto, Failure) ->
genFailure([State | Tail], Goto, Failure) ->
#{State := Node} = Goto,
%% find the starting point: the parent's failure node
FailureState = maps:get(State, Failure, 0),
FailState = maps:get(State, Failure, 0),
%% children
Kvs = maps:to_list(Node),
%% find failure node for all children
NewFailure = genFailureInner(Kvs, FailureState, Goto, Failure),
NewFailure = genFailureInner(Kvs, FailState, Goto, Failure),
%% add children states to the queue
NewQueue = Tail ++ maps:values(Node),
genFailure(NewQueue, Goto, NewFailure).
genFailure(NewQueue, Goto, NewFailure);
genFailure([], _Goto, Failure) ->
Failure.
%%
%% @param FailureState
genFailureInner([], _FailureState, _Goto, Failure) ->
%% @param FailState
genFailureInner([], _FailState, _Goto, Failure) ->
Failure;
genFailureInner([{Word, State}|Tail], FailureState, Goto, Failure) ->
NewFailure = findFailureNode(Word, State, FailureState, Goto, Failure),
genFailureInner(Tail, FailureState, Goto, NewFailure).
genFailureInner([{Word, State} | Tail], FailState, Goto, Failure) ->
NewFailure = findFailureNode(Word, State, FailState, Goto, Failure),
genFailureInner(Tail, FailState, Goto, NewFailure).
%%
findFailureNode(Word, State, FailureState, Goto, Failure) ->
#{FailureState := Node} = Goto,
findFailureNode(Word, State, FailState, Goto, Failure) ->
#{FailState := Node} = Goto,
case Node of
#{Word := TheFailureState} ->
#{Word := TheFailState} ->
%%
Failure#{State => TheFailureState};
Failure#{State => TheFailState};
_ ->
case FailureState =:= 0 of
case FailState =:= 0 of
true -> %%
Failure;
_ -> %%
NewFailureState = maps:get(FailureState, Failure, 0),
findFailureNode(Word, State, NewFailureState, Goto, Failure)
NewFailState = maps:get(FailState, Failure, 0),
findFailureNode(Word, State, NewFailState, Goto, Failure)
end
end.
genHead() ->
<<"-module(acsTrees).\n\n-export([goto/1, failure/1, output/1]).\n\n">>.
<<"-module(acsTrees).\n\n-compile([deterministic, no_line_info]).\n\n-export([goto/1, failOut/1]).\n\n">>.
genGoto(Goto, StrAcc) ->
Kvs = maps:to_list(Goto),
@ -116,47 +125,51 @@ genGoto(Goto, StrAcc) ->
doGenGoto(SortKvs, StrAcc).
doGenGoto([], StrAcc) ->
StrAcc;
<<StrAcc/binary, "goto(_) -> undefined.\n\n">>;
doGenGoto([{K, V}], StrAcc) ->
<<StrAcc/binary, "goto(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ".\n\n">>;
case maps:size(V) > 0 of
true ->
<<StrAcc/binary, "goto(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ";\ngoto(_) -> undefined.\n\n">>;
_ ->
<<StrAcc/binary, "goto(_) -> undefined.\n\n">>
end;
doGenGoto([{K, V} | SortKvs], StrAcc) ->
NewStrAcc = <<StrAcc/binary, "goto(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ";\n">>,
doGenGoto(SortKvs, NewStrAcc).
genFailure(Goto, StrAcc) ->
Kvs = maps:to_list(Goto),
SortKvs = lists:sort(Kvs),
doGenFailure(SortKvs, StrAcc).
doGenFailure([], StrAcc) ->
StrAcc;
doGenFailure([{K, V}], StrAcc) ->
<<StrAcc/binary, "failure(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ".\n\n">>;
doGenFailure([{K, V} | SortKvs], StrAcc) ->
NewStrAcc = <<StrAcc/binary, "failure(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ";\n">>,
doGenFailure(SortKvs, NewStrAcc).
genOutput(Goto, StrAcc) ->
Kvs = maps:to_list(Goto),
SortKvs = lists:sort(Kvs),
doGenOutput(SortKvs, StrAcc).
doGenOutput([], StrAcc) ->
StrAcc;
doGenOutput([{K, V}], StrAcc) ->
<<StrAcc/binary, "output(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ".\n\n">>;
doGenOutput([{K, V} | SortKvs], StrAcc) ->
NewStrAcc = <<StrAcc/binary, "output(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ";\n">>,
doGenOutput(SortKvs, NewStrAcc).
case maps:size(V) > 0 of
true ->
NewStrAcc = <<StrAcc/binary, "goto(", (integer_to_binary(K))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [V]))/binary, ";\n">>,
doGenGoto(SortKvs, NewStrAcc);
_ ->
doGenGoto(SortKvs, StrAcc)
end.
genFailOut([], _Failure, _Output, StrAcc) ->
<<StrAcc/binary, "\nfailOut(_) -> {0, undefined}.\n\n">>;
genFailOut([State], Failure, Output, StrAcc) ->
FailState = maps:get(State, Failure, 0),
Pattern = maps:get(State, Output, undefined),
case FailState /= 0 orelse Pattern /= undefined of
true ->
<<StrAcc/binary, "failOut(", (integer_to_binary(State))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [{FailState, Pattern}]))/binary, ";\nfailOut(_) -> {0, undefined}.\n\n">>;
_ ->
<<StrAcc/binary, ";\nfailOut(_) -> {0, undefined}.\n\n">>
end;
genFailOut([State | SortStates], Failure, Output, StrAcc) ->
FailState = maps:get(State, Failure, 0),
Pattern = maps:get(State, Output, undefined),
case FailState /= 0 orelse Pattern /= undefined of
true ->
NewStrAcc = <<StrAcc/binary, "failOut(", (integer_to_binary(State))/binary, ") -> ", (eFmt:formatBin(<<"~w">>, [{FailState, Pattern}]))/binary, ";\n">>,
genFailOut(SortStates, Failure, Output, NewStrAcc);
_ ->
genFailOut(SortStates, Failure, Output, StrAcc)
end.
genErl(WriteDir, Goto, Failure, Output) ->
HeadStr = genHead(),
GotoStr = genGoto(Goto, HeadStr),
FailureStr = genFailure(Failure, GotoStr),
OutputStr = genOutput(Output, FailureStr),
FailureStr = genFailOut(lists:sort(maps:keys(Goto)), Failure, Output, GotoStr),
FileName = filename:join([WriteDir, "acsTrees.erl"]),
file:write_file(FileName, OutputStr).
file:write_file(FileName, FailureStr).

config/sensitiveWord.txt → src/test/SWord.txt 查看文件


+ 216
- 0
src/test/acTc.erl 查看文件

@ -0,0 +1,216 @@
-module(acTc).
-compile(inline).
-compile({inline_size, 128}).
-export([
tc/1
, tc/2
, tc/3
, ts/4
, tm/5
, cvrTimeUnit/3
, test/1
]).
%% Measure the execution time (in nanoseconds) for Fun().
-spec tc(Fun :: function()) -> {Time :: integer(), Value :: term()}.
tc(F) ->
T1 = erlang:monotonic_time(),
Val = F(),
T2 = erlang:monotonic_time(),
Time = cvrTimeUnit(T2 - T1, native, nanosecond),
{Time, Val}.
%% Measure the execution time (in nanoseconds) for Fun(Args).
-spec tc(Fun :: function(), Arguments :: [term()]) -> {Time :: integer(), Value :: term()}.
tc(F, A) ->
T1 = erlang:monotonic_time(),
Val = apply(F, A),
T2 = erlang:monotonic_time(),
Time = cvrTimeUnit(T2 - T1, native, nanosecond),
{Time, Val}.
%% Measure the execution time (in nanoseconds) for an MFA.
-spec tc(Module :: module(), Function :: atom(), Arguments :: [term()]) -> {Time :: integer(), Value :: term()}.
tc(M, F, A) ->
T1 = erlang:monotonic_time(),
Val = apply(M, F, A),
T2 = erlang:monotonic_time(),
Time = cvrTimeUnit(T2 - T1, native, nanosecond),
{Time, Val}.
-spec cvrTimeUnit(Time :: integer(), FromUnit :: erlang:time_unit(), ToUnit :: erlang:time_unit()) -> ConvertedTime :: integer().
cvrTimeUnit(Time, FromUnit, ToUnit) ->
try
FU =
case FromUnit of
native -> erts_internal:time_unit();
perf_counter -> erts_internal:perf_counter_unit();
nanosecond -> 1000 * 1000 * 1000;
microsecond -> 1000 * 1000;
millisecond -> 1000;
second -> 1
end,
TU =
case ToUnit of
native -> erts_internal:time_unit();
perf_counter -> erts_internal:perf_counter_unit();
nanosecond -> 1000 * 1000 * 1000;
microsecond -> 1000 * 1000;
millisecond -> 1000;
second -> 1
end,
case Time < 0 of
true -> (TU * Time - (FU - 1)) div FU;
_ -> TU * Time div FU
end
catch
_ : _ ->
erlang:error(badarg, [Time, FromUnit, ToUnit])
end.
%% LoopTimes是循环次数
%% utTc:ts(LoopTimes, Module, Function, ArgsList).
%% SpawnProcessesCount是并发的进程数 LoopTimes是循环次数
%% utTc:tm(ProcessesCount, LoopTimes, Module, Function, ArgsList).
doTc(M, F, A) ->
T1 = erlang:monotonic_time(),
apply(M, F, A),
T2 = erlang:monotonic_time(),
cvrTimeUnit(T2 - T1, native, nanosecond).
distribution(List, Aver) ->
distribution(List, Aver, 0, 0).
distribution([H | T], Aver, Greater, Less) ->
case H > Aver of
true ->
distribution(T, Aver, Greater + 1, Less);
false ->
distribution(T, Aver, Greater, Less + 1)
end;
distribution([], _Aver, Greater, Less) ->
{Greater, Less}.
%% ===================================================================
%% test: one process test N times
%% ===================================================================
ts(LoopTime, M, F, A) ->
{Max, Min, Sum, Aver, Greater, Less} = loopTs(LoopTime, M, F, A, LoopTime, 0, 0, 0, []),
io:format("=====================~n"),
io:format("execute Args:~p~n", [A]),
io:format("execute Fun :~p~n", [F]),
io:format("execute Mod :~p~n", [M]),
io:format("execute LoopTime:~p~n", [LoopTime]),
io:format("MaxTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Max), float_to_binary(Max / 1000000000, [{decimals, 6}, compact])]),
io:format("MinTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Min), float_to_binary(Min / 1000000000, [{decimals, 6}, compact])]),
io:format("SumTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Sum), float_to_binary(Sum / 1000000000, [{decimals, 6}, compact])]),
io:format("AvgTime: ~10s(ns) ~10s(s)~n", [float_to_binary(Aver, [{decimals, 6}, compact]), float_to_binary(Aver / 1000000000, [{decimals, 6}, compact])]),
io:format("Grar : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Greater), float_to_binary(Greater / LoopTime, [{decimals, 2}]), <<"%">>]),
io:format("Less : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Less), float_to_binary(Less / LoopTime, [{decimals, 2}]), <<"%">>]),
io:format("=====================~n").
loopTs(0, _M, _F, _A, LoopTime, Max, Min, Sum, List) ->
Aver = Sum / LoopTime,
{Greater, Less} = distribution(List, Aver),
{Max, Min, Sum, Aver, Greater, Less};
loopTs(Index, M, F, A, LoopTime, Max, Min, Sum, List) ->
Nanosecond = doTc(M, F, A),
NewSum = Sum + Nanosecond,
if
Max == 0 ->
NewMax = NewMin = Nanosecond;
Max < Nanosecond ->
NewMax = Nanosecond,
NewMin = Min;
Min > Nanosecond ->
NewMax = Max,
NewMin = Nanosecond;
true ->
NewMax = Max,
NewMin = Min
end,
loopTs(Index - 1, M, F, A, LoopTime, NewMax, NewMin, NewSum, [Nanosecond | List]).
%% ===================================================================
%% Concurrency test: N processes each test one time
%% ===================================================================
tm(ProcCnt, LoopTime, M, F, A) ->
loopSpawn(ProcCnt, M, F, A, self(), LoopTime),
{Max, Min, Sum, Aver, Greater, Less} = collector(ProcCnt, 0, 0, 0, ProcCnt, []),
io:format("=====================~n"),
io:format("execute Args:~p~n", [A]),
io:format("execute Fun :~p~n", [F]),
io:format("execute Mod :~p~n", [M]),
io:format("execute LoopTime:~p~n", [LoopTime]),
io:format("execute ProcCnts:~p~n", [ProcCnt]),
io:format("MaxTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Max), float_to_binary(Max / 1000000000, [{decimals, 6}, compact])]),
io:format("MinTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Min), float_to_binary(Min / 1000000000, [{decimals, 6}, compact])]),
io:format("SumTime: ~10s(ns) ~10s(s)~n", [integer_to_binary(Sum), float_to_binary(Sum / 1000000000, [{decimals, 6}, compact])]),
io:format("AvgTime: ~10s(ns) ~10s(s)~n", [float_to_binary(Aver, [{decimals, 6}, compact]), float_to_binary(Aver / 1000000000, [{decimals, 6}, compact])]),
io:format("Grar : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Greater), float_to_binary(Greater / LoopTime, [{decimals, 2}]), <<"%">>]),
io:format("Less : ~10s(cn) ~10s(~s)~n", [integer_to_binary(Less), float_to_binary(Less / LoopTime, [{decimals, 2}]), <<"%">>]),
io:format("=====================~n").
loopSpawn(0, _, _, _, _, _) ->
ok;
loopSpawn(ProcCnt, M, F, A, CollectorPid, LoopTime) ->
spawn_link(fun() -> worker(LoopTime, M, F, A, CollectorPid) end),
loopSpawn(ProcCnt - 1, M, F, A, CollectorPid, LoopTime).
collector(0, Max, Min, Sum, ProcCnt, List) ->
Aver = Sum / ProcCnt,
{Greater, Less} = distribution(List, Aver),
{Max, Min, Sum, Aver, Greater, Less};
collector(Index, Max, Min, Sum, ProcCnt, List) ->
receive
{result, Nanosecond} ->
NewSum = Sum + Nanosecond,
if
Max == 0 ->
NewMax = NewMin = Nanosecond;
Max < Nanosecond ->
NewMax = Nanosecond,
NewMin = Min;
Min > Nanosecond ->
NewMax = Max,
NewMin = Nanosecond;
true ->
NewMax = Max,
NewMin = Min
end,
collector(Index - 1, NewMax, NewMin, NewSum, ProcCnt, [Nanosecond | List])
after 1800000 ->
io:format("execute time out~n"),
ok
end.
worker(LoopTime, M, F, A, CollectorPid) ->
SumTime = loopTm(LoopTime, M, F, A, 0),
CollectorPid ! {result, SumTime}.
loopTm(0, _, _, _, SumTime) ->
SumTime;
loopTm(LoopTime, M, F, A, SumTime) ->
Microsecond = doTc(M, F, A),
loopTm(LoopTime - 1, M, F, A, SumTime + Microsecond).
test(N) ->
M1 = erlang:monotonic_time(),
timer:sleep(N),
M2 = erlang:monotonic_time(),
Time = cvrTimeUnit(M2 - M1, native, nanosecond),
io:format("IMY******************111 ~p~n", [Time]),
S1 = erlang:system_time(nanosecond),
timer:sleep(N),
S2 = erlang:system_time(nanosecond),
io:format("IMY******************222 ~p~n", [S2 - S1]).

config/test.txt → src/test/test.txt 查看文件

@ -1,3 +1,8 @@
去你妈的
你妈

Loading…
取消
儲存