如何使用erlang列表:map函数

发布于 2024-08-07 13:54:26 字数 1055 浏览 1 评论 0原文

以下是一个 erlang 函数。我不明白lists: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 ], 我不知道如何修复它。

The following is a erlang function. I don't understand how lists:map function is used here.
Could someone please explain?

% 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) }.

Thanks.

also, I don't know the proper syntax when using this function. For example, I have a dummy() function take 1 parameter. I get an error while trying to time the dummy function.

moduleName:time_it(moduleName:dummy/1, 10, 100).

the above would evaluate to illegal expression.

Actually, now with the correct syntax, the function can be invoked correctly with:

moduleName:time_it(fun moduleName:dummy/1, 10, 100).

However, it will throw a exception saying invoking dummy function without passing any parameter. I think this line is the villain, [ G() || _ <- NN ], I have no idea how to fix it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你怎么这么可爱啊 2024-08-14 13:54:26

函数

T0 = now(),                           % start timer
[ G() || _ <- NN ],                   % make N calls to F
1.0e-6*timer:now_diff(now(), T0)/N    % average time per call

这里使用map来执行MM每个元素的 。 map 将返回一个相同大小的新列表,其中新列表的每个元素是将上述函数应用于 MM 相应元素的结果。

您可以像这样调用 time_it

moduleName:time_it(fun moduleName:dummy/1, 10, 100).

map is used here to execute the function

T0 = now(),                           % start timer
[ G() || _ <- NN ],                   % make N calls to F
1.0e-6*timer:now_diff(now(), T0)/N    % average time per call

for each element of MM. map will return a new list of the same size, where each element of the new list is the result of applying the above function to the corresponding element of MM.

You can invoke time_it like:

moduleName:time_it(fun moduleName:dummy/1, 10, 100).
你好,陌生人 2024-08-14 13:54:26

time_it 函数中 lists:map 的作用只是运行内部函数 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).

The purpose of lists:map in the time_it function is just to run the inner function M times. When you see this pattern:

L = lists:seq(1,M),
lists:map(fun(_)-> Foo() end, L)

It just means call Foo() again and again M times, and return the results of each call in a list. It actually makes a list of integers [1,2,3,...N] and then calls Foo() once for each member of the list.
The author of time_it does this same trick again, because time_it needs to call the function you give it N*M times. So inside the outer loop that runs M times they use a different technique to run the inner loop N times:

L = lists:seq(1,N),
[Foo() || _ <- L]

This has exactly the same result as the code above, but this time Foo is called N times.

The reason you are having trouble using time_it with your dummy function is that time_it takes a function with 0 parameters, not 1. So you need to make a dummy function and call it like this:

dummy() -> 
    %% do something here you want to measure
    ok.

measure_dummy() ->
    time_it(fun someModule:dummy/0, 10, 100).
大姐,你呐 2024-08-14 13:54:26

如果您有一个函数 moduleName:dummy/1 您可以执行以下操作之一

  1. 如果您可以编辑 time_it/3,则使其调用 F(constant_parameter) 而不是 <代码>F()。我想情况就是这样。
  2. 否则,调用M1:time_it(fun() -> M2:dummy(constant_parameter) end, N, M)
    dummy 不会被直接调用,而只能由 time_it 内的 F 调用。

If you have a function moduleName:dummy/1 you can do one of the following

  1. If you can edit time_it/3, then make it call F(constant_parameter) instead of F(). I assume this is the case.
  2. Otherwise, call M1:time_it(fun() -> M2:dummy(constant_parameter) end, N, M).
    dummy will not be called directly, but only by F inside time_it.
千紇 2024-08-14 13:54:26
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) 

现在有意义吗?

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).

With these:

T = results(M, fun () ->
                   T0 = now(),
                   repeat(N, G),
                   1.0e-6 * timer:now_diff(now(), T0)/N
               end) 

Make sense, now?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文