Archaelus在this post中建議編寫一個新的格式例程來處理命名參數可能是一個很好的學習練習。因此,本着學習語言的精神,我編寫了一個處理命名參數的格式化例程。打印命名參數
爲例:
1> fout:format("hello ~s{name}, ~p{one}, ~p{two}, ~p{three}~n",[{one,1},{three,3},{name,"Mike"},{two,2}]).
hello Mike, 1, 2, 3
ok
的基準:
1> timer:tc(fout,benchmark_format_overhead,["hello ~s{name}, ~p{one}, ~p{two}, ~p{three}~n",[{one,1},{name,"Mike"},{three,3},{two,2}],100000]).
{421000,true}
= 4.21us per call
雖然我懷疑第在這個開銷的大部分是由於循環,作爲一個調用函數與一個循環產生一個響應在< 1us。
1> timer:tc(fout,benchmark_format_overhead,["hello ~s{name}, ~p{one}, ~p{two}, ~p{three}~n",[{one,1},{name,"Mike"},{three,3},{two,2}],1]).
{1,true}
如果在erlang中有更好的基準測試方法,請告訴我。
驗證碼: (已按照道格的建議進行了修訂)
-module(fout).
-export([format/2,benchmark_format_overhead/3]).
benchmark_format_overhead(_,_,0)->
true;
benchmark_format_overhead(OString,OList,Loops) ->
{FString,FNames}=parse_string(OString,ONames),
benchmark_format_overhead(OString,OList,Loops-1).
format(OString,ONames) ->
{FString,FNames}=parse_string(OString,ONames),
io:format(FString,FNames).
parse_string(FormatString,Names) ->
{F,N}=parse_format(FormatString),
{F,substitute_names(N,Names)}.
parse_format(FS) ->
parse_format(FS,"",[],"").
parse_format("",FormatString,ParamList,"")->
{lists:reverse(FormatString),lists:reverse(ParamList)};
parse_format([${|FS],FormatString,ParamList,"")->
parse_name(FS,FormatString,ParamList,"");
parse_format([$}|_FS],FormatString,_,_) ->
throw({'unmatched } found',lists:reverse(FormatString)});
parse_format([C|FS],FormatString,ParamList,"") ->
parse_format(FS,[C|FormatString],ParamList,"").
parse_name([$}|FS],FormatString,ParamList,ParamName) ->
parse_format(FS,FormatString,[list_to_atom(lists:reverse(ParamName))|ParamList],"");
parse_name([${|_FS],FormatString,_,_) ->
throw({'additional { found',lists:reverse(FormatString)});
parse_name([C|FS],FormatString,ParamList,ParamName) ->
parse_name(FS,FormatString,ParamList,[C|ParamName]).
substitute_names(Positioned,Values) ->
lists:map(fun(CN)->
case lists:keysearch(CN,1,Values) of
false ->
throw({'named parameter not found',CN,Values});
{_,{_,V}} ->
V
end end,
Positioned).
,因爲這是一個學習的過程,我希望那些更有經驗的使用Erlang可以給我提示如何改進我的代碼。
乾杯, 邁克
爲了計時的目的,如果測量速度太快,您應該在循環中運行並取平均值作爲時間 – 2009-01-04 04:52:25
請在標題中更改您的問題,我不知道您問我是否看到了它在搜索結果中。 – Soviut 2009-07-22 17:25:13