gpt4 book ai didi

c++ - 继承真的不影响性能吗?

转载 作者:行者123 更新时间:2023-12-01 14:49:39 31 4
gpt4 key购买 nike

我在互联网上发现(herehere),继承不会影响类的性能。我一直对此感到好奇,因为我一直在为渲染引擎编写一个矩阵模块,这个模块的速度对我来说非常重要。

在我写完之后:

  • 基础:通用矩阵类
  • 派生自基础:方形实现
  • 派生自派生:方阵的 3-dim 和 4-dim 实现

我决定测试它们并面临实例化的性能问题

所以主要的问题是:

  1. 在我的案例中出现这些性能问题的原因是什么?为什么它们通常会发生?
  2. 在这种情况下我应该忘记继承吗?

这些类通常是这样的:

template <class t>
class Matrix
{
protected:
union {
struct
{
unsigned int w, h;
};
struct
{
unsigned int n, m;
};
};

/** Changes flow of accessing `v` array members */
bool transposed;

/** Matrix values array */
t* v;

public:
~Matrix() {
delete[] v;
};
Matrix() : v{}, transposed(false) {};

// Copy
Matrix(const Matrix<t>& m) : w(m.w), h(m.h), transposed(m.transposed) {
v = new t[m.w * m.h];
for (unsigned i = 0; i < m.g_length(); i++)
v[i] = m.g_v()[i];
};

// Constructor from array
Matrix(unsigned _w, unsigned _h, t _v[], bool _transposed = false) : w(_w), h(_h), transposed(_transposed) {
v = new t[_w * _h];
for (unsigned i = 0; i < _w * _h; i++)
v[i] = _v[i];
};

/** Gets matrix array */
inline t* g_v() const { return v; }
/** Gets matrix values array size */
inline unsigned g_length() const { return w * h; }

// Other constructors, operators, and methods.
}



template<class t>
class SquareMatrix : public Matrix<t> {
public:
SquareMatrix() : Matrix<t>() {};
SquareMatrix(const Matrix<t>& m) : Matrix<t>(m) {};

SquareMatrix(unsigned _s, t _v[], bool _transpose) : Matrix<t>(_s, _s, _v, _transpose) {};
// Others...
}

template<class t>
class Matrix4 : public SquareMatrix<t> {
public:
Matrix4() : SquareMatrix<t>() {};
Matrix4(const Matrix<t>& m) : SquareMatrix<t>(m) {}

Matrix4(t _v[16], bool _transpose) : SquareMatrix<t>(4, _v, _transpose) {};
// Others...
}


为了进行测试,我使用了这个

void test(std::ofstream& f, char delim, std::function<void(void)> callback) {
auto t1 = std::chrono::high_resolution_clock::now();
callback();
auto t2 = std::chrono::high_resolution_clock::now();
f << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << delim;
//std::cout << "test took " << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << " microseconds\n";
}

性能问题

对于单个类初始化,没有任何问题 - 每个类几乎每次都在 5 微秒以下。但是后来我决定扩大初始化的数量,并且发生了一些麻烦

我用长度为 500 的数组运行了每个测试 100 次

1。使用默认构造函数初始化类

Raw results

我刚刚测试了数组的初始化

结果是(平均时间以微秒为单位):

  • 矩阵 25.19
  • SquareMatrix 40.37(损失 37.60%)
  • Matrix4 58.06(SquareMatrix 损失 30.47%)

在这里我们已经可以看到巨大的差异

这是代码

int main(int argc, char** argv)
{
std::ofstream f("test.csv");
f << "Matrix\t" << "SquareMatrix\t" << "Matrix4\n";

for (int k = 0; k < 100; k++) {
test(f, '\t', []() {
Matrix<long double>* a = new Matrix<long double>[500];
});

test(f, '\t', []() {
SquareMatrix<long double>* a = new SquareMatrix<long double>[500];
});

test(f, '\n', []() {
Matrix4<long double>* a = new Matrix4<long double>[500];
});
}

f.close();

return 0;
}

2。使用默认构造函数和填充的类初始化

Raw results

测试类实例数组的初始化并用自定义矩阵填充它们

结果(以微秒为单位的平均时间):

  • 矩阵 402.8
  • SquareMatrix 475(损失 15.20%)
  • Matrix4 593.86(SquareMatrix 损失 20.01%)

代码

int main(int argc, char** argv)
{
long double arr[16] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14,15,16
};

std::ofstream f("test.csv");
f << "Matrix\t" << "SquareMatrix\t" << "Matrix4\n";

for (int k = 0; k < 100; k++) {
test(f, '\t', [&arr]() {
Matrix<long double>* a = new Matrix<long double>[500];
for (int i = 0; i < 500; i++)
a[i] = Matrix<long double>(4, 4, arr);
});

test(f, '\t', [&arr]() {
SquareMatrix<long double>* a = new SquareMatrix<long double>[500];
for (int i = 0; i < 500; i++)
a[i] = SquareMatrix<long double>(4, arr);
});

test(f, '\n', [&arr]() {
Matrix4<long double>* a = new Matrix4<long double>[500];
for (int i = 0; i < 500; i++)
a[i] = Matrix4<long double>(arr);
});
}

f.close();

return 0;
}

3。用类实例填充 vector

Raw results

将自定义矩阵推回 vector

结果(以微秒为单位的平均时间):

  • 矩阵 4498.1
  • SquareMatrix 4693.93(损失 4.17%)
  • Matrix4 4960.12(其 SquareMatrix 损失 5.37%)

代码

int main(int argc, char** argv)
{
long double arr[16] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14,15,16
};

std::ofstream f("test.csv");
f << "Matrix\t" << "SquareMatrix\t" << "Matrix4\n";

for (int k = 0; k < 100; k++) {
test(f, '\t', [&arr]() {
std::vector<Matrix<long double>> a = std::vector<Matrix<long double>>();
for (int i = 0; i < 500; i++)
a.push_back(Matrix<long double>(4, 4, arr));
});

test(f, '\t', [&arr]() {
std::vector<SquareMatrix<long double>> a = std::vector<SquareMatrix<long double>>();
for (int i = 0; i < 500; i++)
a.push_back(SquareMatrix<long double>(4, arr));
});

test(f, '\n', [&arr]() {
std::vector<Matrix4<long double>> a = std::vector<Matrix4<long double>>();
for (int i = 0; i < 500; i++)
a.push_back(Matrix4<long double>(arr));
});
}

f.close();

return 0;
}

如果需要全部源码可以看here进入 matrix.hmatrix.cpp

最佳答案

Does inheritance really not affect performance?

是的。只要不涉及虚方法,继承就不会影响运行时性能。 (因为只有这样你才必须在运行时推断类型并调用相应的虚方法覆盖)。事实上,如果你看得更深一些,你就会知道 C++ 继承大多只是静态的东西,即在编译时完成。

What's the reason of these performance issues in my case and why may they happen in general?

启用优化后这些功能似乎运行良好?

Should I forget about inheritance in such cases?

在这种对性能敏感的情况下,您唯一需要做的就是避免虚方法。

与此问题无关的内容。我已经阅读了你的代码。也许在头文件中实现模板会更好?

关于c++ - 继承真的不影响性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58892865/

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