类对象定义如下:
class myArrayDynamic
{
private:
unsigned m_n;
double* m_data = nullptr;
public:
// Copy constructor
inline myArrayDynamic(const myArrayDynamic& a)
{
assert(m_n == a.m_n);
for (int i = 0; i < m_n; ++i)
{
m_data[i] = a.m_data[i];
}
}
// Move constructor
inline myArrayDynamic(myArrayDynamic&& a)
{
m_n = a.m_n;
m_data = a.m_data;
a.m_data = nullptr;
}
inline myArrayDynamic(const unsigned n)
:
m_n(n)
{
this->m_data = new double[m_n];
}
inline myArrayDynamic(const unsigned n, const double& v)
:
m_n(n)
{
this->m_data = new double[m_n];
for (unsigned i = 0; i < m_n; ++i)
{
this->m_data[i] = v;
}
}
~myArrayDynamic()
{
if (m_data) delete[] m_data;
}
// Copy assignment
inline myArrayDynamic& operator=(const myArrayDynamic& a)
{
assert(m_n == a.m_n);
for (int i = 0; i < m_n; ++i)
{
m_data[i] = a.m_data[i];
}
return *this;
}
// Move assignment
inline myArrayDynamic& operator=(myArrayDynamic&& a)
{
m_n = a.m_n;
m_data = a.m_data;
a.m_data = nullptr;
return *this;
}
inline myArrayDynamic& operator=(const double& v)
{
for (unsigned i = 0; i < m_n; ++i)
{
m_data[i] = v;
}
return *this;
}
inline myArrayDynamic& operator+=(const myArrayDynamic& m)
{
for (unsigned i = 0; i < m_n; ++i)
{
m_data[i] += m.m_data[i];
}
return *this;
}
inline double& operator[] (const unsigned i)
{
return m_data[i];
}
inline const double& operator[] (const unsigned i) const
{
return m_data[i];
}
};
这是第一个测试代码:
myArrayDynamic mDynamic(MN, 0.), mDynamic0(MN, 1.e-6);
auto start = high_resolution_clock::now();
for (int i = 0; i < iterMax; ++i)
{
mDynamic += mDynamic0;
}
auto end = high_resolution_clock::now();
nanoseconds nsec = end - start;
std::cout << "construct(N, v): "
<< std::setprecision(3) << std::setw(10) << std::scientific
<< nsec.count() * 1e-6 << " ms\n" << std::flush;
std::cout << mDynamic[0] << "\n";
这是第二个测试代码:
myArrayDynamic mDynamic(MN), mDynamic0(MN);
mDynamic = 0.;
mDynamic0 = 1.e-6;
auto start = high_resolution_clock::now();
for (int i = 0; i < iterMax; ++i)
{
mDynamic += mDynamic0;
}
auto end = high_resolution_clock::now();
nanoseconds nsec = end - start;
std::cout << "construct(N): "
<< std::setprecision(3) << std::setw(10) << std::scientific
<< nsec.count() * 1e-6 << " ms\n" << std::flush;
std::cout << mDynamic[0] << "\n";
MN = 200; iterMax = 1000000
对于两个测试代码
唯一的区别是它们使用不同的构造函数
代码编译为(gcc版本9.4.0):
g++ -O3 -std=c++17 test.cpp -o test
在 ubuntu-20.04.3 上使用第 12 代 Intel(R) Core(TM) i7-12700H 运行代码
construct(N, v): 4.678e+01 ms
construct(N): 1.462e+01 ms
可以看出,上述测试代码的性能存在巨大差异
但是为什么呢?如何理解上述行为?
我有一点点改变。
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std;
using chrono::high_resolution_clock;
using chrono::nanoseconds;
class myArrayDynamic
{
private:
unsigned m_n;
double* m_data = nullptr;
public:
inline myArrayDynamic(const unsigned n)
:
m_n(n)
{
//this->
m_data = new double[m_n];
}
inline myArrayDynamic(const unsigned n, const double& v)
:
m_n(n)
{
//this->
m_data = new double[m_n];
for (unsigned i = 0; i < m_n; ++i)
{
//this->
m_data[i] = v;
}
}
~myArrayDynamic()
{
if (m_data) delete[] m_data;
}
inline myArrayDynamic& operator=(const double& v)
{
for (unsigned i = 0; i < m_n; ++i)
{
m_data[i] = v;
}
return *this;
}
inline myArrayDynamic& operator+=(const myArrayDynamic& m)
{
for (unsigned i = 0; i < m_n; ++i)
{
m_data[i] += m.m_data[i];
}
return *this;
}
} ;
int main() {
const unsigned MN = 200, iterMax = 1000000;
myArrayDynamic mDynamic(MN, 0.), mDynamic0(MN, 1.e-6);
auto start = high_resolution_clock::now();
for (int i = 0; i < iterMax; ++i)
{
mDynamic += mDynamic0;
}
auto end = high_resolution_clock::now();
nanoseconds nsec = end - start;
std::cout << "construct(N, v): "
<< std::setprecision(3) << std::setw(10) << std::scientific
<< nsec.count() * 1e-6 << " ms\n" << std::flush;
//std::cout << mDynamic[0] << "\n";
}
int main2() {
const unsigned MN = 200, iterMax = 1000000;
myArrayDynamic mDynamic(MN), mDynamic0(MN);
mDynamic = 0.;
mDynamic0 = 1.e-6;
auto start = high_resolution_clock::now();
for (int i = 0; i < iterMax; ++i)
{
mDynamic += mDynamic0;
}
auto end = high_resolution_clock::now();
nanoseconds nsec = end - start;
std::cout << "construct(N): "
<< std::setprecision(3) << std::setw(10) << std::scientific
<< nsec.count() * 1e-6 << " ms\n" << std::flush;
//std::cout << mDynamic[0] << "\n";
}
在
myArrayDynamic
构造函数中,this
代表类obj本身,不需要使用它们。 [仅在上面的例子中]
但实际上,编译器并不识别它,只是根据脚本进行编译。
所以你必须先调用 obj 本身,然后再次调用它的数组。
所以这就是为什么的答案。