【问题标题】:Performance improvement with local objects使用本地对象提高性能
【发布时间】:2016-12-11 22:21:12
【问题描述】:

很多时候我们需要在循环中初始化某些类的对象以进行操作:

假设我有一个类/结构:

class employee
{
  //member variables
  //member methods - getter/setters,etc
}

现在假设我想对数组中的每个员工进行操作。

方法一:

for (loop on array of 10 employees)
{
  employee emp(loop element);  //using constructor of employee for initialization
  //operate on the current loop element using emp
}

这样,根据我的理解,将创建 10 个 emp 对象,直到循环结束。现在由于这不包括动态内存分配,一旦控制退出循环,所有 10 个对象将被删除(和内存占用10 个将被释放)或仅删除最后一个对象(& 9 个对象占用的内存不会被释放)。

方法二:

for (loop on array of 10 employees)
{
  employee *emp=new employee(loop element);  //using constructor of employee for initialization
  //operate on the current loop element using emp
  delete emp;
  emp = nullptr;
}

这里它在程序员的控制中,所以我们可以在每次循环迭代中自己释放内存。虽然这也会导致频繁分配和释放堆内存,并且如果循环用于大量员工,可能会导致性能下降。

请帮助我解决方法 1 中提到的查询,并请建议上述方法中哪一种好,以及是否有更好的方法?

【问题讨论】:

    标签: c++ performance


    【解决方案1】:

    方法 1 更好,因为您不需要依赖平衡 newdelete,因此不太可能泄漏内存:如果您的“操作”代码在方法 2 中抛出异常,那么 @ 987654323@ 将不会被调用。在方法 1 中,如果堆栈展开时抛出异常,则将调用析构函数

    从概念上讲是的,在两种 方法中,employee 的析构函数将在循环的每个单独迭代中被调用。也就是说,允许编译器将其作为一种优化策略进行调整如果这样做没有副作用。

    【讨论】:

      【解决方案2】:

      我不确定我是否理解这个问题。如果我有一个对象循环并且我不想修改对象,我不会复制它们。我只会使用 const 引用。

      for(auto const& e: employees) {
          // operate on e
      }
      

      如果对象被修改,即调用非常量成员函数,我会使用非常量引用

      for(auto&& e: employees) {
          // operate on e
      }
      

      在您的示例中,“临时”员工对象是堆栈分配的或堆分配的。在第一种情况下,对象是在堆栈上创建的。这意味着编译器只需将堆栈指针增加(或减少)到一个值,即堆栈上有足够的空间来保存员工对象,然后使用构造函数对其进行初始化。不会进行堆分配,并且只有一个员工类型的对象存活加上循环中的一个。当作用域结束时,生命周期结束。在任何情况下,循环结束时都不会有十个对象。

      第二种情况与生命周期相同,但在堆上分配对象。这要慢得多,但是当您一直删除对象时,生命周期是相同的。在这种情况下,我建议使用std::unique_ptr,因为它也是异常安全的,并且可以为您节省手动内存管理。当操作部分抛出异常时,您的代码存在内存泄漏。

      【讨论】:

        【解决方案3】:

        方法 1 将在栈上分配员工对象,这肯定比使用动态内存分配器(堆)更快。在每次迭代中,员工对象都会超出范围,因此每次都会调用其析构函数。这是堆栈的好处,当您离开范围时,它会自动“收集垃圾”(请参阅​​Is a destructor called when an object goes out of scope?)。

        【讨论】:

          猜你喜欢
          • 2016-11-29
          • 1970-01-01
          • 2012-07-14
          • 1970-01-01
          • 2017-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多