为什么写入不相关的文件导致加载功能如此之慢?

时间:2013-03-13 13:37:24

标签: matlab matlab-load

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

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

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行的最后三行。在我的实际程序中,load并不是那么接近另一位,所以直到我决定不信任分析器才发生这种情况。我的问题是:这里发生了什么?为什么会发生这种情况,我应该留意这样更奇怪的行为吗?

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

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

  • 上面显示的两个for循环是相同的,除了第二个循环在底部有三行,每次迭代都写入一个临时文件。
  • 第二个循环运行时间要长得多:结论是最后三行是速度增加的原因。当它们被删除时,代码再次快速。
  • 但是,探查器会将第二个循环的属性用于最后三个语句。相反,它告诉我我的load函数调用 - 与第一个循环完全相同的调用(更快) - 现在需要4秒而不是0.2秒。因此,最后三行的存在导致 load变慢(我忽略了这一点;这是否有可能?),或者MATLAB探查器错误地报告{{} 1}}显然时需要4秒钟。

无论哪种方式,我觉得发生了一些非常奇怪的事情。

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

3 个答案:

答案 0 :(得分:3)

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

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

这意味着所有其他行一起占用的时间少于0.01,因此每行的舍入量为零秒。

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

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

答案 1 :(得分:3)

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

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

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

无论如何,感谢那些看起来很抱歉的人,答案结果与问题完全不同。使用依赖整个搜索路径的功能时要注意!

答案 2 :(得分:1)

我得到了MATLAB 2012b的剖析器生成的以下报告,我没有看到错误。 enter image description here enter image description here enter image description here