我已经确定了我的c ++代码中的瓶颈,我的目标是加快速度。如果条件为真,我将项目从一个向量移动到另一个向量。
在python中,这样做的pythonic方法是使用列表解析:
my_vector = [x for x in data_vector if x > 1]
我已经破解了一种在C ++中执行此操作的方法,并且它运行正常。但是,我在一个while循环中调用了数百万次,而且速度很慢。我对内存分配了解不多,但我认为我的问题与使用push_back
重新分配内存有关。有没有办法以不同的方式分配我的内存来加速这段代码? (在my_vector
- 循环完成之前,我不知道for
应该有多大。
std::vector<float> data_vector;
// Put a bunch of floats into data_vector
std::vector<float> my_vector;
while (some_condition_is_true) {
my_vector.clear();
for (i = 0; i < data_vector.size(); i++) {
if (data_vector[i] > 1) {
my_vector.push_back(data_vector[i]);
}
}
// Use my_vector to render graphics on the GPU, but do not change the elements of my_vector
// Change the elements of data_vector, but not the size of data_vector
}
答案 0 :(得分:7)
使用std::copy_if
,并最初为data_vector.size()
保留my_vector
(因为这是谓词可以评估为true的最大元素数量):
std::vector<int> my_vec;
my_vec.reserve(data_vec.size());
std::copy_if(data_vec.begin(), data_vec.end(), std::back_inserter(my_vec),
[](const auto& el) { return el > 1; });
请注意,如果您希望谓词评估为true的次数远小于reserve
的大小,则可以避免此处data_vector
调用。
答案 1 :(得分:1)
运行代码两次,第一次只计算,你需要多少新元素。然后使用reserve
已经分配了所需的所有内存。
while (some_condition_is_true) {
my_vector.clear();
int newLength = 0;
for (i = 0; i < data_vector.size(); i++) {
if (data_vector[i] > 1) {
newLength++;
my_vector.reserve(newLength);
for (i = 0; i < data_vector.size(); i++) {
if (data_vector[i] > 1) {
my_vector.push_back(data_vector[i]);
}
}
// Do stuff with my_vector and change data_vector
}
答案 2 :(得分:1)
我怀疑分配my_vector
是个问题,特别是如果while
循环执行多次,因为my_vector
的容量应该很快就足够了。
但是要确保您可以在my_vector
中保留与data_vector
相对应的容量:
my_vector.reserve(data_vector.size());
while (some_condition_is_true) {
my_vector.clear();
for (auto value : data_vector) {
if (value > 1)
my_vector.push_back(value);
}
}
答案 3 :(得分:1)
如果您使用的是Linux,则可以为my_vector
保留内存,以防止std::vector
重新分配,这是您案例中的瓶颈。请注意,由于过度使用,保留不会浪费内存,因此保留值的任何粗略估计值都将满足您的需求。在您的情况下,data_vector
的大小就足够了。 while
循环之前的这行代码应该解决瓶颈问题:
my_vector.reserve(data_vector.size());
答案 4 :(得分:1)
虽然其他人为您的查询发布了各种优秀的解决方案,但似乎对内存分配仍然没有太多解释,您不太了解,所以我想与您分享我对此主题的了解。希望这会有所帮助。
首先,在C ++中,有几种类型的内存:stack
,heap
,data segment
。
Stack
用于局部变量。有一些与之相关的重要功能,例如,它们将被自动解除分配,对它的操作非常快,其大小取决于操作系统,并且很小,因此在stack
中存储一些KB数据可能会导致内存溢出等等。
Heap
的内存可以全局访问。至于它的重要特性,我们有,它的大小可以根据需要动态扩展,其大小更大(远大于stack
),对它的操作比stack
慢,手动释放内存是需要(在现今的操作系统中,内存将在程序结束时自动释放),等等。
Data segment
用于全局变量和静态变量。事实上,这块存储器可以分成更小的部分,例如BBS。
在您的情况下,使用vector
。实际上,vector
的元素存储在其内部动态数组中,即具有动态数组大小的内部数组。在早期的C ++中,可以在stack
内存上创建动态数组,但是,不再是这种情况。要创建动态数组,必须在heap
上创建它。因此,vector
的元素存储在heap
上的内部动态数组中。实际上,要动态增加数组的大小,需要一个进程memory reallocation
。但是,如果vector
用户不断扩大他或她的vector
,那么reallocation
费用的间接费用将会很高。为了解决这个问题,vector
首先会分配一块大于当前需求的内存,即分配内存以备将来使用。因此,在您的代码中,每次调用memory reallocation
时都不会执行push_back()
。但是,如果要复制的vector
非常大,则为将来使用而保留的内存将不足。然后,memory allocation
将会发生。要解决这个问题,可以使用vector.reserve()
。
我是新手。希望我在分享时没有犯错。 希望这会有所帮助。