【问题标题】:Defining variable outside of a loop [duplicate]在循环外定义变量[重复]
【发布时间】:2014-10-01 00:56:41
【问题描述】:

两者之间是否有任何性能差异:

uint a;
for (uint i = 0 ; i < n ; ++i)
{
    a = i;
}

和:

for (uint i = 0 ; i < n ; ++i)
{
    uint a;
    a = i;
}

第二段代码是否会导致程序多次而不是一次创建变量(分配内存或某事)?如果不是,是因为两个代码是等价的还是因为一些编译器优化?

【问题讨论】:

    标签: c++ performance variables memory


    【解决方案1】:

    我希望所有现代编译器在这两种情况下都能生成相同的代码。

    您可能会惊讶地发现,对于大多数编译器而言,两种情况之间的开销绝对没有任何差异。

    简而言之,这些类型的变量在堆栈上实例化,编译器为每个函数计算实例化函数内部所有局部变量所需的最大堆栈量,并在函数入口处分配所需的堆栈空间点。

    当然,如果不是简单的int,而是在其构造函数中有一些具有非平凡复杂性的类,那么它肯定会在几个方面产生很大的不同。但是对于这样一个简单的int,绝对没有。

    【讨论】:

      【解决方案2】:

      假设uint 是基本数据类型,我会说它们是相同的。当然,除了您可以在第一个示例中的循环之后使用a 之外。这是因为将基本数据类型放在堆栈上的成本是微不足道的,编译器可以优化这种情况,因此内存实际上只保留了一次,就好像你在循环外声明了它一样。

      如果uint 是一个类,将它放在循环之外并重用它可能会更快。例如,在循环之前声明 std::string 并在循环内重用它可能比每次迭代创建一个新字符串更快。这是因为字符串可以重用其现有的动态内存分配。

      你可以看看你的编译器的反汇编,看看有什么不同。

      【讨论】:

        【解决方案3】:

        第二个示例必须稍微慢一些,因为每次迭代都会重新定义 a。这意味着要留出空间来存储 a 的最大可能值(在这种情况下,可能是 4 字节的内存)。该空间的分配是一个将被执行的命令,所以我认为它比较慢。有关系吗?应该不会吧。

        【讨论】:

        • “必须”是错误的。它可能完全一样。此外,int 可能超过 2 个字节(通常是)
        • 此外,使用任何健全的编译器,在堆栈上,在循环中的每个入口点,绑定一个 int(无论是两个字节还是四个字节)所需的工作量正好是 0 个 CPU 周期。
        • @NeilKirk 我改进了我的措辞并更正了关于 uint 为 2 个字节的部分......我在想一个 ushort。至于最后一条评论,无论是否完全可以忽略不计,它仍然会影响速度。
        猜你喜欢
        • 1970-01-01
        • 2023-03-02
        • 1970-01-01
        • 1970-01-01
        • 2015-10-09
        • 1970-01-01
        • 2014-06-15
        • 2020-04-05
        相关资源
        最近更新 更多