不同性能的默认初始化和值初始化struct [英] Different performance for default initialized and value initialized struct

查看:151
本文介绍了不同性能的默认初始化和值初始化struct的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的结构与数组:

I have a simple struct with an array:

struct A
{
  uint32_t arr[size];
};

我有两个函数,使用默认初始化和值初始化创建它:

I have two functions, which create it using default initialization and value initialization:

template<class T>
void testDefault()
{
  T* pa = new T;  // Default
  use(*pa);
  delete pa;
}

template<class T>
void testValue()
{
  T* pa = new T();  // Value
  use(*pa);
  delete pa;
}

我对这些功能面临不同的性能。有趣的是,性能差异取决于我如何声明结构的默认构造函数。我有三种方法:

I'm facing different performance for those functions. The funny thing is that performance differences vary depending on how I declare default constructor of the struct. I have three ways:

struct A
{
  uint32_t arr[size];
  // Implicit constructor
};

struct B
{
  uint32_t arr[size];
  B() {};  // Empty constructor
};

struct C
{
  uint32_t arr[size];
  C() = default;  // Defaulted constructor
};

我认为从编译器的角度来看,它们都是一样的。从来没有我这么错。我已经运行了 testDefault() testValue() code>, B C 这是我有:

I thought they are all the same from compiler's point of view. Never have been I so wrong. I did run both testDefault() and testValue() several times with structs A, B and C and measured performance. Here is what I have:

Default initialization (implict constructor) done in 880ms
Value initialization (implict constructor) done in 1145ms
Default initialization (empty constructor) done in 867ms
Value initialization (empty constructor) done in 865ms
Default initialization (defaulted constructor) done in 872ms
Value initialization (defaulted constructor) done in 1148ms

请注意,隐式和默认构造函数的性能明显更糟。对于两种不同的初始化形式,只有空构造函数正确地显示相同的性能。

Note how performance is clearly worse for both implicit and defaulted constructors. Only empty constructor correctly shows the same performance for both different initialization forms.

我用VC ++,gcc和clang测试了这个。请参见 gcc的在线演示。时间非常持久。

I tested this with VC++, gcc and clang. See online demo for gcc. Timings are quite persistent.

我假设是:


  1. 默认值UDT的初始化是相同的事情

  2. 所有演示的定义默认构造函数的方法都是做同样的事情

  3. 这些结构体的默认构造函数应该保留数组处于不确定状态

由于所有编译器都显示相同的时序,所以似乎我缺少一些东西。任何人可以向我解释这些时间吗?

Since all the compilers exhibit the same timings, it seems like I'm missing something. Can anyone please explain me these timings?

(另请参见我的问题

(See also my question Why compilers put zeros into arrays while they do not have to? on the same topic. I give some links to cppreference there.)

推荐答案

让我们看看 value-initialize 的定义:


要初始化类型T的对象意味着:

To value-initialize an object of type T means:


  • 是没有默认构造函数(12.1)或用户提供或删除的默认构造函数的(可能是cv限定的)类类型,则对象是默认初始化的;

  • if [...];

  • 如果T是一个数组,那么这个对象是零初始化的类型,则每个元素都是值初始化的;

  • 否则,对象将初始化为零。

  • if T is a (possibly cv-qualified) class type with either no default constructor (12.1) or a default constructor that is user-provided or deleted, then the object is default-initialized;
  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized [...];
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized.

此外,我们来看看构造函数中使用的形容词:

Also let's review the adjectives in use here for constructors:


  • - 您声明了构造函数 - 您已声明构造函数,并且未将其设置为 = default c> = delete

  • 默认 / li>
  • 已声明为默认 - 标记为 =默认; 或隐式生成

  • user-declared - you declared the constructor
  • user-provided - you declared the constructor and didn't set it to = default or = delete
  • default - can be called with no arguments
  • declared as defaulted - marked = default; or implicitly generated as such

查看您的课程:


  • A 有一个默认构造函数,默认声明为默认值,而不是用户提供的。

  • C 一个默认的构造函数,用户声明为默认值,而不是用户提供的。

  • A has a default constructor which is implicitly declared as defaulted, and not user-provided.
  • C has a default constructor which is user-declared as defaulted, and not user-provided.

- 初始化适用。对象是零初始化的,意味着 arr 已清零。

So the second bullet point in the definition of value-initialize applies. The object is zero-initialized, meaning the arr is zeroed out.


  • code> B 有一个由用户提供的默认构造函数。

  • B has a default constructor which is user-provided.

point-value-initialize适用于 B ;值初始化与此处的默认初始化相同,并且 arr 未归零。

So the first bullet point of value-initialize applies to B; value-initialization is the same as default-initialization here, and arr is not zeroed out.

似乎符合预期: A C 的值初始化零 arr ,其他情况则不然。

Your timings correctly seem to correspond to what is expected: value-initialization of A or C zeroes out arr and the other cases don't.

这篇关于不同性能的默认初始化和值初始化struct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆