【问题标题】:Does using global variables impact performance in MATLAB?使用全局变量会影响 MATLAB 中的性能吗?
【发布时间】:2016-03-30 18:52:32
【问题描述】:

据我了解,MATLAB 在向其他函数发送参数时不能使用pass by reference。我正在做音频处理,我经常需要将波形作为参数传递给函数,而且因为 MATLAB 使用pass by value 来处理这些参数,所以当我这样做时它确实会占用大量 RAM。

我正在考虑使用global 变量作为将我的波形传递给函数的方法,但在我阅读的所有地方似乎普遍认为这是一个坏主意,对于代码组织和潜在的性能问题.. . 但我还没有真正阅读任何关于这可能如何影响性能的详细答案......

我的问题:在1)方面,使用全局变量(大小 > 100MB)将参数传递给 MATLAB 中的其他函数有什么负面影响性能2) 一般代码组织和良好实践

编辑: 从下面@Justin 的回答中可以看出,当您不修改函数中的参数时,MATLAB 有时会使用按引用传递!由此,我有一个关于全局变量性能的第二个相关问题:

使用全局变量会比使用pass by reference 函数参数慢吗?

【问题讨论】:

  • 良好实践而言,其中一个陷阱是您可能会突然覆盖在其他函数中的函数内部使用的变量。因此,可能很难跟踪更改,并且因此在函数之间来回切换可能会导致意外行为。如果您将全局变量称为 ha 等,这种情况尤其常见(当变量不是 global 时,这当然也会导致错误的阅读)
  • This post on matlabtips.com 详细解释了不同类型的变量以及为什么使用global 通常不受欢迎。
  • 相关:“GLOBAL could be very inefficient”Don't use global, don't use eval。而Matlab在OOP的情况下可以use pass by reference。是的,全局变量会更慢(你自己测试一下),它们也会让你的代码更难维护和理解。

标签: performance matlab global


【解决方案1】:

MATLAB 确实使用按引用传递,但也使用写时复制。也就是说,您的变量将通过引用传递给函数(因此不会在 RAM 上加倍),但是如果您在函数内更改变量,那么 MATLAB 将创建一个副本并更改副本(离开原版不受影响)。

这个事实似乎不太为人所知,但有一个good post on Loren's blog在讨论它。

底线:听起来您根本不需要使用全局变量(正如@Adriaan 所说,这是一个坏主意)。

【讨论】:

  • 很好,但是使用全局变量真的会影响性能吗(以负面的方式)?我会说不是
  • @NikosM。是的,请参阅 Loren 的帖子和我在上面链接的帖子(也可以点击进入 global variables 上的 wiki 页面)
  • 阅读文章(加上一些顶级 cmets,不是全部),但没有提到任何关于使用全局变量的内容,尤其是它们的性能与作为参数传递的变量,wiki 文章没有提到 matlab-具体信息或性能信息
  • 很好的答案!但是在某些情况下,我确实需要修改参数的内容(例如对我的波形应用校准),但感谢您纠正了我对 MATLAB 中的pass by reference 的误解! @Adriaan 我和@Nikos M. 在一起,因为这些帖子确实涉及写入时复制的异常,但我没有看到任何具体提及或全局变量性能示例。从@Justin's awesome answer here,我在我的问题中添加了一个附加部分,我认为这将进一步阐明我对全局变量性能的理解。
  • 这个答案与@horchler 对我的问题的评论相结合,让我对全局变量的性能以及在什么情况下需要使用它们有了一个很好的概述。
【解决方案2】:

虽然像贾斯汀建议的那样依赖写时复制通常是最佳选择,但您可以轻松实现按引用传递。由于 Matlab oop 几乎与 Matlab 2015b 或更高版本中的传统函数一样快,因此使用 handle 是一个合理的选择。

【讨论】:

  • 我现在正在研究这个,但这听起来是最好的选择,因为我偶尔需要在函数中修改我的参数值,所以@Justin 的回答虽然很棒,但并不总是适用。
  • 如果我理解这一点......为了在我修改函数中传递的参数值的情况下“强制pass by reference”,比如一个矩阵对象,我会有制作一个用户定义的matrix 类,它是Handle 的子类?在文档中,它描述了一些对象是句柄,句柄如何表现,以及如何检查对象是否是句柄,但没有关于如何将 non-handle object 转换为 handle object 的信息(如果事实上是可能)。
  • 我在接下来的几天内无法访问 Matlab,如果有人可以提供更多信息,请随时更新我的​​答案。
【解决方案3】:

昨天我遇到了一个有趣的global 变量用例。我尝试使用parfor并行化一段代码(1200行,主函数内部有多个函数,不是我写的)。

出现了一些奇怪的错误,原来这段代码写入了一个日志文件,但是使用了多个函数来写入日志文件。而不是每次函数要写入时打开和关闭相关的日志文件,这很慢,文件ID被设置为global,这样所有的写入函数都可以访问它。

对于串行情况,这非常有意义,但是当尝试并行化它时,使用global 显然也破坏了工作实例的范围。突然间,我们有 4 个工作人员都试图写入同一个日志文件,这导致了一些奇怪的错误。

总而言之,我坚持my position 认为使用global 变量通常是个坏主意,尽管我可以看到它在特定情况下的用途,前提是您知道自己在做什么.

【讨论】:

    【解决方案4】:

    Matlab may increase performance 中大量使用全局变量。这是因为您可以避免在某些情况下复制数据。

    在尝试进行此类性能调整之前,请仔细考虑项目的成本,即全局变量带来的许多缺点。使用全局变量也有一些陷阱,会对性能产生不良影响,这些可能很难避免(尽管可能)。任何充斥着全局变量的代码往往难以理解。

    如果您想查看全局变量用于性能,您可以查看我制作的这个real-time toolbox for optical flow。这是我所知道的本地 Matlab 中唯一能够实时光流的项目。使用全局变量是可行的原因之一。这也是代码很难掌握的一个原因:全局是邪恶的。

    可以以这种方式使用全局变量并不是为使用它们而争论的方式,而是暗示应该使用 Matlabs 不灵活的工作空间概念和低效的全局变量替代方案(如 guidata/getappdata/setappdata)来更新一些东西。

    【讨论】:

    • “...可能会提高性能”与另一个糟糕的设计相比。您链接的问题又链接到this post,它指出全局变量会干扰 JIT。这很有意义。将变量作为参数传递给函数应该始终优于使用全局变量。
    • @Cris Luengo。这种糟糕的设计可以作为完全支持的 Matlab 函数(guidata、getappdata、setappdata)使用是有原因的,因为需要它。如果您曾经使用 Matlab 设计过一个可以快速处理大量数据的 GUI,您就会知道原因。但是您知道吗,无论如何,不​​应使用 Matlab 来获得这种速度。当您认为使用全局变量是一种可行的加速方法时,请在完成原型设计时更改语言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2011-06-12
    • 1970-01-01
    • 2017-01-27
    • 2013-09-25
    • 1970-01-01
    相关资源
    最近更新 更多