在循环外生成所有随机数或动态生成它是否更好

时间:2016-08-18 18:56:50

标签: performance matlab random

通常,如果在每次迭代中都需要生成一个随机数,最好在开始时生成一次所有随机数,然后在每次迭代中生成从表中生成的数字。

然而,我今天遇到了一个与这种直觉相反的问题。我有一个长度为N的数字向量,在每次迭代中,我必须重新调整这个向量的顺序并做一些事情。

我实现了两种方式:第一种方式与我刚才描述的完全一样,即在每次迭代中,我调用函数

V = randperm(N)

在第二种方法中,在循环之前,我调用函数

W = arrayfun(@(x)randperm(N),(1:T-1)','UniformOutput',0);
W = cell2mat(W);

这里T是迭代的总数。然后在每次迭代中,我只从矩阵W中检索行。然后,2个方法的其余代码完全相同。

然而,我发现第二个代码比第一个代码慢得多(我检查过:W = arrayfun(@(x)randperm(N),(1:T-1)','UniformOutput',0);的命令不会花费太多时间)。我运行了探查器,我发现在第二个代码中调用函数ismember>ismemberR2012a比第一个代码多3倍。我无法弄清楚原因。

2 个答案:

答案 0 :(得分:0)

首先,您应该注意,randpermarrayfun函数都是mex个文件。所以我的第一个猜测是arrayfun是一个调用randperm并将其结果存储在cell并重复此过程的进程。这使得它有点慢。如果您尝试在第一个解决方案中执行相同操作,则会花费更多。 我也进行了一些测试。 我不知道NT的比例。但我仍在我的机器上测试了这些功能

N=10000;
T = 1000;
tic;
for ii=1:T-1
    V=randperm(N);
end
toc;
tic;
W = arrayfun(@(x)randperm(N),(1:T-1)','UniformOutput',0);
W = cell2mat(W);
toc;

结果是:

N=10000T=1000

Elapsed time is 0.849627 seconds.
Elapsed time is 0.996933 seconds.

我认为原因是第一个解决方案被称为T-1次,而第二个解决方案只被调用一次。它必须管理大细胞分配。

enter image description here

即使这样做也不会提高代码的性能:

tic;
for ii=1:T-1
Z = arrayfun(@(x)randperm(N),ii,'UniformOutput',0);
end
toc;

Elapsed time is 0.827387 seconds.
Elapsed time is 0.966013 seconds.
Elapsed time is 0.951093 seconds.

然后运行探查器: enter image description here

  • 如果您可以动态生成随机数,生成和存储它们的重点是什么,然后在需要时再次加载它们?

  • 这些数字是在不同的运行中收集的,显然由于执行时间的随机性,它们并不一致。

答案 1 :(得分:0)

请注意,如果N小于10,您可能需要使用perms

循环之前:

% get all available permutations:
W = perms(1:N);
% get a list of T random permutations from W:
p = randi(length(W),T,1);

然后在循环中使用pW

V = W(p(k),:); % for iteration k