我正在尝试解决DP问题,我创建了一个2D数组,并一直填充2D数组。使用不同的测试用例多次调用我的函数。当我使用矢量>时,我得到超出时间限制的错误(所有测试用例需要超过2秒)。但是,当我使用bool [] []时,花费更少的时间(大约0.33秒),我得到一个通行证。
有人可以帮我理解为什么会有矢量>效率低于bool [] []。
bool findSubsetSum(const vector<uint32_t> &input)
{
uint32_t sum = 0;
for (uint32_t i : input)
sum += i;
if ((sum % 2) == 1)
return false;
sum /= 2;
#if 1
bool subsum[input.size()+1][sum+1];
uint32_t m = input.size()+1;
uint32_t n = sum+1;
for (uint32_t i = 0; i < m; ++i)
subsum[i][0] = true;
for (uint32_t j = 1; j < n; ++j)
subsum[0][j] = false;
for (uint32_t i = 1; i < m; ++i) {
for (uint32_t j = 1; j < n; ++j) {
if (j < input[i-1])
subsum[i][j] = subsum[i-1][j];
else
subsum[i][j] = subsum[i-1][j] || subsum[i-1][j - input[i-1]];
}
}
return subsum[m-1][n-1];
#else
vector<vector<bool>> subsum(input.size()+1, vector<bool>(sum+1));
for (uint32_t i = 0; i < subsum.size(); ++i)
subsum[i][0] = true;
for (uint32_t j = 1; j < subsum[0].size(); ++j)
subsum[0][j] = false;
for (uint32_t i = 1; i < subsum.size(); ++i) {
for (uint32_t j = 1; j < subsum[0].size(); ++j) {
if (j < input[i-1])
subsum[i][j] = subsum[i-1][j];
else
subsum[i][j] = subsum[i-1][j] || subsum[i-1][j - input[i-1]];
}
}
return subsum.back().back();
#endif
}
谢谢你, 艾哈迈德。
答案 0 :(得分:0)
如果你需要一个矩阵并且你需要做高性能的东西,它并不总是使用嵌套std::vector
或std::array
的最佳解决方案,因为它们在内存中不是连续的。不连续的内存访问会导致更高的缓存未命中。
查看更多:
std::vector and contiguous memory of multidimensional arrays
Is the data in nested std::arrays guaranteed to be contiguous?
另一方面,bool twoDAr[M][N]
被保证是连续的。它确保减少缓存未命中。
查看更多:
C / C++ MultiDimensional Array Internals
了解缓存友好代码:
答案 1 :(得分:0)
有人可以帮我理解为什么会有矢量&gt;再少一点 效率高于bool [] []。
二维bool
数组实际上只是一个大的 M * N 的大型一维bool
数组,没有间隙项目之间。
二维std::vector
不存在;不仅仅是一个大的一维std::vector
,而是一个std::vector
的{{1}}。外部矢量本身没有记忆间隙,但在各个矢量的内容区域之间可能存在间隙。这取决于你的编译器如何实现非常特殊的std::vector<bool>
类,但如果你的元素数量足够大,那么动态分配是不可避免的,以防止堆栈溢出,而这仅仅意味着指向分离的内存区域。
一旦您需要从分离的内存区域访问数据,事情就会变慢。
这是一个可能的解决方案:
std::vector
的{{1}}。std::vector<bool>
大小(input.size() + 1) * (sum + 1)
来避免模板专精化,并根据需要将元素转换为std::vector<char>
。答案 2 :(得分:-1)
如果从一开始就你知道数组的输入大小,使用数组总是比Vector
或更快。因为vector是数组的包装器,所以是更高级的实现。它的好处是在需要时为您分配额外的空间,如果您有固定大小的元素,则不需要这些空间。
如果您在需要1D阵列的地方遇到问题,那么差异可能不会让您感到困扰(您拥有单个矢量和单个阵列)。但是创建一个2D数组,您还可以创建vector
类的多个实例,因此array
和vector
之间的时差乘以元素数量你的容器里有你的代码很慢。
这个时差背后有许多原因,但最明显的原因当然是调用vector
构造函数。您正在调用函数subsum.size()
次。其他答案提到的记忆问题是另一个原因。
为了提高性能,建议您在代码中尽可能使用array
。即使您需要使用vector
,也应该尽量减少向量完成的重新调整大小的数量(保留,预分配),从而实现对array
的更紧密的实现。