以下是erlang功能。我不明白列表如何:这里使用map函数。 有人可以解释一下吗?
% perform M runs with N calls to F in each run.
% For each of the M runs, determine the average time per call.
% Return, the average and standard deviation of these M results.
time_it(F, N, M) ->
G = fun() -> F(), ok end,
NN = lists:seq(1, N),
MM = lists:seq(1, M),
T = lists:map(
fun(_) ->
T0 = now(), % start timer
[ G() || _ <- NN ], % make N calls to F
1.0e-6*timer:now_diff(now(), T0)/N % average time per call
end,
MM
),
{ avg(T), std(T) }.
感谢。
另外,使用此功能时我不知道正确的语法。例如,我有一个dummy()函数取1参数。我在尝试计算虚拟函数时遇到错误。
moduleName:time_it(moduleName:dummy/1, 10, 100).
以上将评估为非法表达。
实际上,现在使用正确的语法,可以使用以下命令正确调用该函数:
moduleName:time_it(fun moduleName:dummy/1, 10, 100).
但是,它会抛出一个异常,说在不传递任何参数的情况下调用虚函数。我认为这一行是恶棍,[ G() || _ <- NN ],
我不知道如何修复它。
答案 0 :(得分:6)
map
来执行函数
T0 = now(), % start timer
[ G() || _ <- NN ], % make N calls to F
1.0e-6*timer:now_diff(now(), T0)/N % average time per call
表示MM
的每个元素。 map
将返回相同大小的新列表,其中新列表的每个元素都是将上述函数应用于MM
的相应元素的结果。
您可以调用time_it
,如:
moduleName:time_it(fun moduleName:dummy/1, 10, 100).
答案 1 :(得分:4)
lists:map
函数中time_it
的目的只是运行内部函数M次。当你看到这种模式时:
L = lists:seq(1,M),
lists:map(fun(_)-> Foo() end, L)
它只是意味着一次又一次地呼叫Foo()
M次,并在列表中返回每个呼叫的结果。它实际上会生成一个整数列表[1,2,3,...N]
,然后为列表的每个成员调用Foo()
一次。
time_it
的作者再次做同样的伎俩,因为time_it
需要调用你给它N * M次的函数。因此,在运行M次的外循环中,他们使用不同的技术来运行内循环N次:
L = lists:seq(1,N),
[Foo() || _ <- L]
这与上面的代码完全相同,但这次Foo
被称为N次。
你在使用虚函数time_it
时遇到问题的原因是time_it
采用0参数的函数,而不是1.所以你需要创建一个虚函数并调用它:
dummy() ->
%% do something here you want to measure
ok.
measure_dummy() ->
time_it(fun someModule:dummy/0, 10, 100).
答案 2 :(得分:1)
如果您有一个函数moduleName:dummy / 1,您可以执行以下操作之一
time_it/3
,请拨打F(constant_parameter)
而不是F()
。我认为情况就是这样。M1:time_it(fun() -> M2:dummy(constant_parameter) end, N, M)
。
dummy不会直接调用,只能由time_it中的F调用。答案 3 :(得分:0)
results(N, F) when N >= 0 -> results(N, F, []).
results(0, _, Acc) -> lists:reverse(Acc);
results(N, F, Acc) -> results(N-1, F, [F() | Acc]).
repeat(0, F) -> ok;
repeat(N, F) when N > 0 ->
F(),
repeat(N-1, F).
有了这些:
T = results(M, fun () ->
T0 = now(),
repeat(N, G),
1.0e-6 * timer:now_diff(now(), T0)/N
end)
现在有意义吗?