注意:这仅在在线IDE中得到确认,我自己笔记本电脑上的测试无法确认。
让我们用几乎相同的程序测试两个容器的性能,即计算第一个999999
Collatz序列的长度。我以非常类似的方式使用std::array
和std::vector
来缓存前几个元素。事实证明,std::vector
解决方案比std::array
解决方案快3.5倍。这对我来说很奇怪,因为我被告知动态分配的std::vector
执行速度比std::array
处于核心的静态分配数组要慢。
std::array
本身是否比std::vector
慢?如果是,为什么?如果不是,我在使用std::array
以及如何修复它时我做错了什么?
#include <iostream>
#include <array>
#include <cstdint>
#include <ctime>
std::array<std::uint_fast16_t, 999999> cache;
std::uint_fast16_t getCollatzLength(std::uint_fast64_t val) {
uint_fast16_t excessiveLength = 0;
while(val > 999999) {
if(val%2 == 0)
val /= 2;
else
val = 3*val+1;
++excessiveLength;
}
if(cache[val-1] == 0) {
if(val%2 == 0)
cache[val-1] = getCollatzLength(val/2) + 1;
else
cache[val-1] = getCollatzLength(3*val+1) + 1;
}
return cache[val-1] + excessiveLength;
}
int main()
{
std::clock_t tStart = std::clock();
cache.fill(0);
cache[0] = 1;
std::uint_fast16_t largest = 0;
for(int i = 1; i <= 999999; ++i) {
auto cmax = getCollatzLength(i);
if(cmax > largest)
largest = cmax;
}
std::cout << largest << '\n';
std::cout << "Time taken: " << (double)(std::clock() - tStart)/CLOCKS_PER_SEC << '\n';
}
以上std::array
解决方案runs in 0.067222
#include <iostream>
#include <vector>
#include <cstdint>
#include <ctime>
std::vector<std::uint_fast16_t> cache(999999, 0);
std::uint_fast16_t getCollatzLength(std::uint_fast64_t val) {
uint_fast16_t excessiveLength = 0;
while(val > 999999) {
if(val%2 == 0)
val /= 2;
else
val = 3*val+1;
++excessiveLength;
}
if(cache[val-1] == 0) {
if(val%2 == 0)
cache[val-1] = getCollatzLength(val/2) + 1;
else
cache[val-1] = getCollatzLength(3*val+1) + 1;
}
return cache[val-1] + excessiveLength;
}
int main()
{
std::clock_t tStart = std::clock();
cache[0] = 1;
std::uint_fast16_t largest = 0;
for(int i = 1; i <= 999999; ++i) {
auto cmax = getCollatzLength(i);
if(cmax > largest)
largest = cmax;
}
std::cout << largest << '\n';
std::cout << "Time taken: " << (double)(std::clock() - tStart)/CLOCKS_PER_SEC << '\n';
}
以上std::vector
解决方案runs in 0.0191