gpt4 book ai didi

c++ - 默认初始化和值初始化结构的不同性能

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:27:24 30 4
gpt4 key购买 nike

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

struct A
{
uint32_t arr[size];
};

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

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;
}

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

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
};

我认为从编译器的角度来看它们都是一样的。我从来没有这么错过。我确实使用结构 AB 多次运行了 testDefault()testValue() C 和测量性能。这是我所拥有的:

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

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

我用 VC++、gcc 和 clang 测试了这个。参见 online demo for gcc .计时非常持久。

我的假设是:

  1. UDT 的默认和值初始化是一回事
  2. 所有演示的定义默认构造函数的方法都在做同样的事情
  3. 这些结构的默认构造函数应该使数组的内容处于不确定状态

由于所有编译器都显示相同的时序,所以我似乎遗漏了什么。谁能给我解释一下这些时间安排?

(另请参阅我关于同一主题的问题 Why compilers put zeros into arrays while they do not have to?。我在那里提供了一些指向 cppreference 的链接。)

最佳答案

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

To value-initialize an object of type T means:

  • 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.

另外让我们回顾一下这里用于构造函数的形容词:

  • user-declared - 您声明了构造函数
  • 用户提供 - 您声明了构造函数但未将其设置为 = default= delete
  • 默认 - 可以不带参数调用
  • 声明为默认值 - 标记为 = default; 或隐式生成

查看您的类(class):

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

因此适用值初始化定义中的第二个要点。该对象是零初始化的,这意味着 arr 被清零。

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

因此值初始化的第一个要点适用于B;这里的value-initialization和default-initialization是一样的,arr没有清零。

您的计时似乎正确地符合预期:AC 的值初始化将 arr 归零,而其他情况则不't.

关于c++ - 默认初始化和值初始化结构的不同性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38192687/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com