使用本地对象提高性能

时间:2016-08-05 13:17:46

标签: c++ performance

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

假设我有一个类/结构:

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

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

方法1:

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个对象(& memory占用10将被释放)或只是最后一个对象将被删除(并且9个对象占用的内存不会被释放)。

方法2:

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和方法中提到的问题。请建议上述哪种方法是好的,如果有更好的方法呢?

3 个答案:

答案 0 :(得分:1)

方法1更好,因为您不需要依赖于deletedelete的平衡,因此它不太可能泄漏内存:如果您的"操作上"代码是在方法2中引发异常然后employee被调用。在方法1中,如果在堆栈展开时抛出异常,则会调用析构函数

从概念上讲,是的,在两个方法中,将在循环的每个单独迭代中调用<img src="<?php echo wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'medium');?>"> 的析构函数。也就是说,允许编译器将此作为优化策略,如果没有副作用。

答案 1 :(得分:1)

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

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

如果对象被修改,即调用非const成员函数,我将使用非const引用

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

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

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

答案 2 :(得分:0)

方法1将在堆栈上分配员工对象,这肯定比使用动态内存分配器(堆)更快。在每次迭代时,employee对象都将超出范围,因此每次都会调用其析构函数。这对堆栈来说是好事,它会自动被垃圾收集&#39;离开范围时(见Is a destructor called when an object goes out of scope?)。