代码之家  ›  专栏  ›  技术社区  ›  Pandoro

在C中保留全局变量还是重新创建局部变量?

  •  6
  • Pandoro  · 技术社区  · 15 年前

    我现在已经用Java编程了很多Android。因为性能对于我正在研究的东西非常重要,所以我最终只会向全局变量发送垃圾消息。我想现在每个人都会冲进来告诉我这是有史以来最糟糕的款式,但让我们简单点。对于Android,局部变量意味着垃圾收集,而垃圾收集会破坏性能。

    最近我开始使用NDK。现在我感到有一种强烈的欲望,把所有的局部变量都转换成全局变量。我想知道这在C代码中是否有意义。显然这不是一个好的风格,但如果需要它的速度,我会很乐意牺牲的风格。

    我已经浏览过关于本地和全球的旧线索,但我还没有找到任何关于速度的线索。所以我的问题是,如果我经常调用一个函数,它与局部变量在函数完成后的创建和消亡速度有关吗?或者根本不重要,我可以继续使用局部变量。

    我会自己测试它,但出于某种原因,我的应用程序的性能会像过山车一样上下波动,我怀疑我是否真的能够理解这些数据。我希望有人能在我白白重写整个代码之前帮助我:)

    4 回复  |  直到 15 年前
        1
  •  9
  •   dash-tom-bang    15 年前

    在C语言中,性能差异取决于硬件。在RISC处理器上加载一个全局是更多的指令(因为您必须在单独的指令中加载地址的两部分,而不是添加到堆栈指针中),然后您需要处理缓存问题。在大多数情况下,您可以依靠缓存中的局部变量。使用globals会稍微影响缓存,一些函数可能会受到非常不利的影响。

    如果您在运行应用程序时有大量的性能可变性,那么您关于局部变量的性能影响的断言很可能是无关紧要的。

    在C语言中创建局部变量的“成本”是零;它只是通过碰撞寄存器(堆栈指针)来为局部变量腾出空间。然后通过适当的方法初始化该变量。你应该能通过不经意的检查知道这是不是很贵。当函数退出时,不管您有多少个局部变量,堆栈指针都会返回到其上一个值。

    但是,如果您对“局部变量”的定义是堆分配的对象,那么您将承受内存分配的代价。在我看来,内存分配是非常缓慢的,所以无论你能做什么来摆脱MalOC/FILL(和Java中的“新”),你就会变得更好。(我做游戏,我们倾向于使用dlmalloc,但对于正常使用来说,这太慢了;每次通话400纳秒的加起来很快。)

        2
  •  11
  •   advait    15 年前

    对于Android,局部变量意味着垃圾收集…

    这是一个错误的陈述。局部变量是在堆栈上分配的-不是在堆上动态分配的。签出 this article 在Java中分配什么

    通常,在堆栈上分配的项不需要垃圾收集/释放,并且在执行离开其当前范围后立即“死亡”。堆栈分配/释放为 明显地 比堆分配和垃圾收集更快。

        3
  •  2
  •   Crashworks    15 年前

    在大多数Android手机中的基于MIPS和ARM的CPU上,没有任何理由为了性能而将局部变量移动到全局空间。局部变量存储在堆栈上,堆栈分配是一个单一的操作;而且在调用时,整个堆栈会立即被清理干净。 ret . 把它们移到全球空间,只会让你的逻辑陷入一团混乱的无法辨认的状态,毫无益处。

    创建对象时要担心性能的一个地方是在堆上分配对象时(例如 malloc() )这正是C比垃圾收集语言“更具性能”的地方,因为您可以准确地看到和控制这些malloc何时发生以及何时释放。事实并非如此 马尔洛() 比Java快 new ;相反,因为每个分配对您来说都是透明和明确的,所以您可以做必要的工作,以确保这样缓慢的操作发生得尽可能少。

        4
  •  0
  •   Rube Vogel    15 年前

    顺便说一句,在C函数中声明一个变量static将为您提供一个全局的行为,而不会破坏全局名称空间。

    但是如前所述,在堆栈上声明自动变量需要0时间,访问这些变量也非常快,因此没有太多理由避免函数局部变量。

    如果您真的需要这种极端的优化级别,那么您应该查看内联所有通常调用的函数,以避免调用开销。