6

最近我分析了一些 MATLAB 代码,我很震惊地在一个频繁使用的函数中看到以下内容:

5.76  198694   58 persistent CONSTANTS; 
3.44  198694   59 if isempty(CONSTANTS) % initialize CONSTANTS

换句话说,MATLAB 花了大约 9 秒,超过 198694 次函数调用,声明持久化CONSTANTS并检查它是否已初始化。这占该功能所花费总时间的13% 。

在 MATLAB 中,持久变量真的会带来这么多的性能损失吗?还是我们在这里做错了什么?

更新

@Andrew我尝试了你的示例脚本,我对输出非常非常困惑:

time   calls  line
                6 function has_persistent
6.48  200000    7 persistent CONSTANTS 
1.91  200000    8 if isempty(CONSTANTS) 
                9     CONSTANTS = 42;
               10 end

我尝试了 bench() 命令,它显示我的机器处于示例机器的中间范围。在 Intel(R) Core(TM) i7 CPU、4GB RAM 上运行 Ubuntu 64 位。

4

1 回答 1

9

这是在 Matlab 中使用持久变量的标准方法。你正在做你应该做的事。它会有显着的开销,但你的时间似乎确实有点高。

这是我在 Windows XP x64 下的 3.0 GHz Intel Core 2 QX9650 机器上在 32 位 Matlab R2009b 中运行的类似测试。在其他机器和版本上的类似结果。比您的时间快约 5 倍。

测试:

function call_has_persistent
for i = 1:200000
    has_persistent();
end

function has_persistent
persistent CONSTANTS
if isempty(CONSTANTS)
    CONSTANTS = 42;
end

结果:

  0.89  200000    7 persistent CONSTANTS 
  0.25  200000    8 if isempty(CONSTANTS) 

您在哪个 Matlab 版本、操作系统和 CPU 上运行?CONSTANTS 用什么初始化?Matlab 的 bench() 输出对您的机器来说是否合理?

你的时间似乎确实很高。那里可能存在要修复的错误或配置问题。但是,如果你真的想快速获得 Matlab 代码,标准的建议是“矢量化”它:重构代码,以便在更大的输入数组上进行更少的函数调用,并利用 Matlab 内置的矢量化函数而不是循环或控制结构,以避免首先对函数进行 200,000 次调用。如果可能的话。Matlab 每个函数或方法调用的开销相对较高(有关某些数字,请参阅MATLAB OOP 是否缓慢或我做错了什么?),因此您通常可以通过重构以消除函数调用而不是使单个函数调用更快来获得更多里程。

可能值得在您的机器上对其他一些基本的 Matlab 操作进行基准测试,看看它是否只是“持久”看起来很慢。还可以尝试单独分析这个小的 call_has_persistent 测试脚本,看看你的函数的上下文是否有所作为。

于 2010-09-27T17:31:22.967 回答