4

我刚刚花了一些时间调试一些特别慢的代码,并且完全被 MATLAB 分析器抛弃了。在我看来,这就像一个巨大的错误,所以我想知道是否有人可以对这里发生的事情有所了解。

这是一些会导致问题的代码:

function profiler_test

  %%% Create 20 files with random data

  count = 20;

  for i = 1 : count
    x = rand(3);
    save(sprintf('temp_file_%06d', i), 'x'); 
  end

  %%% Load them in a for loop

  xs = cell(1, count);

  tic;
  for i = 1 : count
    x = load(sprintf('temp_file_%06d', i), 'x');
    xs{i} = x.x;
  end
  toc

  %%% Load them in a for loop, but writing a small log file on the way

  tic;
  for i = 1 : count
    x = load(sprintf('temp_file_%06d', i), 'x');
    xs{i} = x.x;

    file = fopen(sprintf('temp_logfile_%d', i), 'w');
    fprintf(file, 'Success\n');
    fclose(file);
  end
  toc


end

第一个for循环需要 0.239739 秒,第二个循环需要 4.411179。

现在,我应该明确表示我知道我的草率想法,如第二个for循环示例所示,为每个结果创建一个日志文件 - 这是因为我在一个看不到的集群上运行输出,我想要一个函数进度的廉价指示,结果证明这是瓶颈。我很好

然而,我的问题是我花了一天时间试图优化错误的行,因为 MATLAB 分析器这样说:

         1   24   tic; 
         1   25   for i = 1 : count 
4.41    20   26     x = load(sprintf('temp_file_%06d', i), 'x'); 
        20   27     xs{i} = x.x; 
             28     
        20   29     file = fopen(sprintf('temp_logfile_%d', i), 'w'); 
        20   30     fprintf(file, 'Success\n'); 
        20   31     fclose(file); 
        20   32   end 
         1   33   toc

它将执行最后三行所花费的全部load时间放在 for 行上。在我的实际程序中,load它与另一位不太接近,所以直到我决定不信任分析器时才想到它。我的问题是:这里发生了什么?为什么会发生这种情况,我应该提防任何更奇怪的行为吗?

我正在使用 MATLAB 2011a。非常感谢。

编辑:我似乎造成了一些混乱,道歉。情况如下:

  • 上面显示的两个for循环是相同的,除了第二个循环在底部有三行,每次迭代都会写入一个临时文件。
  • 第二个循环需要更长的时间来运行:结论是最后三行是速度增加的罪魁祸首。当它们被删除时,代码又很快了。
  • 但是,分析器不会第二个循环的任何时间归因于最后三个语句。相反,它告诉我我的load函数调用 -与第一个循环完全相同的调用,它更快- 现在需要 4 秒而不是 0.2 秒。因此,要么最后三行的存在导致速度load变慢(我忽略了这一点;这甚至有可能吗?),或者 MATLAB 分析器错误地报告load需要 4 秒,而显然不是

无论哪种方式,在我看来,正在发生一些非常奇怪的事情。

编辑:似乎自己回答了,见下文。更改标题,因为它具有误导性

4

3 回答 3

3

我没有在您的帖子中看到任何错误的证据。

您提到整个循环需要大约4.111并且分析器显示第 26 行需要大约4.11

这意味着所有其他行一起花费的时间少于0.01,因此每行需要四舍五入的零秒。

我的猜测是没有打印零,并且您将其解释为其他行没有计时。

我可能遗漏了一些东西,但到目前为止,MATLAB 提供的输出似乎是一致的。

于 2013-03-13T14:22:20.350 回答
3

其实我想我已经解决了。我错误地得出结论,即在新线路上发生了额外的处理时间,所以我的问题现在有点误导 - 分析器是正确的。但是,我仍然不明白为什么写入临时文件会导致load速度变慢。我有一个想法,那就是试试这个:

file = fopen(sprintf('../temp_logfile_%d', i), 'w');

也就是说,写入父目录中的文件而不是当前工作目录。这消除了问题,而且速度非常快。我猜的原因是当前目录在我的 MATLAB 搜索路径中,还有一堆其他目录。我假设每次 MATLAB 使用一个查看整个搜索路径的函数时load,它都会检查是否有任何目录已被修改,如果是,则重新解析整个文件以查看哪些文件可用。将新文件写入工作目录肯定会导致这种情况。这在我的情况下可能更糟,因为我在工作目录中还有一整棵子目录树,它们是搜索路径的一部分。

无论如何,感谢那些看过并抱歉答案与问题完全不同的人。使用依赖于整个搜索路径的函数时要注意!

于 2013-03-13T14:52:37.173 回答
1

我得到以下由 MATLAB 2012b 的分析器生成的报告,我没有看到错误。 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

于 2013-03-13T14:32:53.900 回答