[英]Why is a vector of classes faster then class with vector
嗨尝试了以下示例,但不明白为什么会这样。
先例
#include <iostream>
#include <vector>
class Ant {
private:
int m_worker;
public:
Ant(int x=0) : m_worker(x) {}
int GetWorker() const {
return m_worker;
}
};
class AntFarm {
private:
std::vector<int> m_worker;
public:
AntFarm() : m_worker(100) {}
int GetWorker(int index) const {
return m_worker.at(index);
}
};
int main() {
AntFarm farm{};
std::vector<Ant> vec(100);
Timer timer_farm{};
Timer timer_ant{};
timer_farm.Start();
for(int j=0;j<10000;j++) {
for(int i=0;i<100;i++) {
int a = farm.GetWorker(i);
}
}
timer_farm.Stop();
timer_ant.Start();
for(int j=0;j<10000;j++) {
for(const auto ant : vec) {
int a = ant.GetWorker();
}
}
timer_ant.Stop();
std::cout << "Farm time passed = "<<timer_farm.Milliseconds() << std::endl;
std::cout << "Ant time passed = "<<timer_ant.Milliseconds() << std::endl;
return 0;
}
Output:
Farm time passed = 30
Ant time passed = 2
我尝试以不同的方式对 Antfarm 进行 model 。 第一种方法是将 Ant 作为 class 并将 Antfarm 存储在 Ant 的向量中。 第二种方法是有一个 AntFarm class ,其中有一个 int 向量。
现在,当我调用 GetWorker 时,我认为第一种方法会比第二种方法慢。 但事实证明,第一种方法是为什么更快。
谁能解释为什么方法 1 比方法 2 更快?!
编辑:
我使用 MSCV 编译器版本 16.9.0+5e4b48a27 和以下编译选项编译 Windows 10 x64 和以下编译选项: /GT /GS /Gs /guard:cf $<$CONFIG:Debug:/RTC1>
我替换了我自己的计时器 class 因为你没有提供一个所以它以纳秒而不是毫秒打印。
在发布版本中运行代码会产生
Farm time passed = 660100
Ant time passed = 0
所以它显然在第二种情况下优化了你的循环,因为它在第一种情况下没有明显的副作用,它仍然可以做一些工作。
更改 AntFarm::GetWorker 以使用数组索引而不是 .at()
int GetWorker(int index) const {
return m_worker[index];
}
得到我们预期的结果。
Farm time passed = 0
Ant time passed = 0
现在我们可以添加一些可见的副作用,以便代码实际运行。 我只是将 a 移到循环外并在完成后打印它,因此无法对其进行优化。
timer_farm.Start();
int a;
for(int j=0;j<10000;j++) {
for(int i=0;i<100;i++) {
a = farm.GetWorker(i);
}
}
timer_farm.Stop();
std::cout << a;
timer_ant.Start();
for(int j=0;j<10000;j++) {
for(const auto ant : vec) {
a = ant.GetWorker();
}
}
timer_ant.Stop();
std::cout << a << "\n";
现在我们在 both.at 和 [] 上都得到了一些结果
m_worker[index]
Farm time passed = 109700
Ant time passed = 318600
m_worker.at(index)
Farm time passed = 550200
Ant time passed = 318200
很明显,在 vector 上使用 .at() 会花费更多,因为它会进行边界检查,但使用数组语法会更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.