海量数据集中的内存优化 我已经实现了一些功能,喜欢问一些基本的东西,因为我对C++没有很好的基础知识。我希望你们都能告诉我什么是我可以从你们身上学到的好方法。(拜托,这不是家庭作业,我周围没有任何专家问我这个问题)

海量数据集中的内存优化 我已经实现了一些功能,喜欢问一些基本的东西,因为我对C++没有很好的基础知识。我希望你们都能告诉我什么是我可以从你们身上学到的好方法。(拜托,这不是家庭作业,我周围没有任何专家问我这个问题),c++,C++,我所做的是;我从一个文件中读取输入的x,y,z,点数据(大约3GB的数据集),然后为每个点计算一个值并存储在一个向量中(结果)。然后,它将在下一个循环中使用。然后,那个向量将不再使用,我需要得到那个内存,因为它包含巨大的数据集。我想我可以通过两种方式做到这一点。 (1) 只需初始化一个向量,然后删除它(见代码1)。(2) 通过分配动态内存,然后再取消分配(参见代码2)。我听说这种取消分配是低效的,因为再次取消分配会消耗内存,或者可能是我误解了 Q1) 我想知道在内存和效率方面的优化方式是什么 问

我所做的是;我从一个文件中读取输入的x,y,z,点数据(大约3GB的数据集),然后为每个点计算一个值并存储在一个向量中(结果)。然后,它将在下一个循环中使用。然后,那个向量将不再使用,我需要得到那个内存,因为它包含巨大的数据集。我想我可以通过两种方式做到这一点。 (1) 只需初始化一个向量,然后删除它(见代码1)。(2) 通过分配动态内存,然后再取消分配(参见代码2)。我听说这种取消分配是低效的,因为再次取消分配会消耗内存,或者可能是我误解了

Q1) 我想知道在内存和效率方面的优化方式是什么

问题2) 另外,我想知道通过引用返回函数是否是给出输出的好方法。(请看代码3)

代码-1

int main(){

    //read input data (my_data)

    vector<double) result;
    for (vector<Position3D>::iterator it=my_data.begin(); it!=my_data.end(); it++){

         // do some stuff and calculate a "double" value (say value)
         //using each point coordinate 

         result.push_back(value);

    // do some other stuff

    //loop over result and use each value for some other stuff
    for (int i=0; i<result.size(); i++){

        //do some stuff
    }

    //result will not be used anymore and thus erase data
    result.clear()
intmain(){
//读取输入数据(my_数据)
vector
擦除
不会释放用于该向量的内存。它会减小大小但不会减小容量,因此该向量仍保留足够的内存用于所有这些双精度运算

使内存再次可用的最佳方法与代码-1类似,但让向量超出范围:

int main() {
    {
        vector<double> result;
        // populate result
        // use results for something
    }
    // do something else - the memory for the vector has been freed
}
原因是,如果调用者使用对该函数的调用作为其自身向量的初始化,则会出现一种称为“命名返回值优化”的方法,并确保尽管您按值返回,但不会生成值的副本

未实现NRVO的编译器是一个糟糕的编译器,可能会出现各种其他令人惊讶的性能故障,但在某些情况下,NRVO不适用-最重要的是,调用方将值分配给变量而不是在初始化中使用。对此,有三种修复方法:

1) C++11引入了移动语义,它基本上通过确保来自临时对象的赋值是便宜的来进行排序

2) 在C++03中,调用方可以玩一个称为“swapimization”的把戏。而不是:

vector<Position3D> foo;
// some other use of foo
foo = ReturnLabel();
向量foo; //foo的其他用法 foo=ReturnLabel();
写:

vector<Position3D> foo;
// some other use of foo
ReturnLabel().swap(foo);
向量foo; //foo的其他用法 ReturnLabel().swap(foo); 3) 您可以编写一个具有更复杂签名的函数,例如通过非常量引用获取
向量
,并将值填入其中,或者将OutputIterator作为模板参数。后者还为调用者提供了更大的灵活性,因为调用者不需要使用
向量
来存储结果,他们可以使用删除其他容器,甚至一次只处理一个容器,而不立即存储整个批次。

erase
不会释放用于向量的内存。它会减少大小,但不会减少容量,因此向量仍然保留足够的内存来存储所有这些双倍

使内存再次可用的最佳方法与代码-1类似,但让向量超出范围:

int main() {
    {
        vector<double> result;
        // populate result
        // use results for something
    }
    // do something else - the memory for the vector has been freed
}
原因是,如果调用者使用对该函数的调用作为其自身向量的初始化,则会出现一种称为“命名返回值优化”的方法,并确保尽管您按值返回,但不会生成值的副本

未实现NRVO的编译器是一个糟糕的编译器,可能会出现各种其他令人惊讶的性能故障,但在某些情况下,NRVO不适用-最重要的是,调用方将值分配给变量而不是在初始化中使用。对此,有三种修复方法:

1) C++11引入了移动语义,它基本上通过确保来自临时对象的赋值是便宜的来进行排序

2) 在C++03中,调用方可以玩一个称为“swapimization”的把戏。而不是:

vector<Position3D> foo;
// some other use of foo
foo = ReturnLabel();
向量foo; //foo的其他用法 foo=ReturnLabel(); 写:

vector<Position3D> foo;
// some other use of foo
ReturnLabel().swap(foo);
向量foo; //foo的其他用法 ReturnLabel().swap(foo);
3) 您可以编写一个具有更复杂签名的函数,例如通过非常量引用获取
向量
,并将值填入其中,或者将OutputIterator作为模板参数。后者还为调用者提供了更大的灵活性,因为调用者不需要使用
向量
来存储结果,他们可以使用使用其他容器,甚至一次只处理一个容器,而不立即存储整批数据。

对于如此庞大的数据集,我将完全避免使用std容器,并使用内存映射文件


如果您喜欢继续使用std::vector,请使用
vector::clear()
vector::swap(std::vector())
来释放分配的内存。

对于如此庞大的数据集,我将完全避免使用std容器,并使用内存映射文件


如果您希望继续使用std::vector,请使用
vector::clear()
vector::swap(std::vector())
释放分配的内存。

您的代码看起来像是第一个循环中的计算值只在第二个循环中被上下文不敏感地使用。换句话说,一旦您在第一个循环中计算了双精度值,您就可以立即对其执行操作,而无需一次存储所有值


如果是这样的话,您应该这样实现它。不必担心大的分配、存储或任何事情。更好的缓存性能。快乐。

您的代码似乎只在第二个循环中不敏感地使用第一个循环的计算值。换句话说,一旦您在第一个循环中计算了双值,您就可以您可以立即对其执行操作,而无需同时存储所有值

如果是这样的话,你应该用这种方式来实现。不用担心我
vector<Position3D> foo;
// some other use of foo
ReturnLabel().swap(foo);
vector<double) result;
    for (vector<Position3D>::iterator it=my_data.begin(); it!=my_data.end(); it++){

         // do some stuff and calculate a "double" value (say value)
         //using each point coordinate 

         result.push_back(value);
vector<double) result (someSuitableNumber,0.0);
void vector<Position3D>::ReturnLabel(VoxelGrid grid, int segment, vector<Position3D> & myVec_out) const //myVec_out is populated inside func
load_my_data()
for_each (p : my_data)
    result.push_back(p)

for_each (p : result)
    reduction.push_back (reduce (p))
file f ("file")
while (f)
    Point p = read_point (f)
    reduction.push_back (reduce (p))
file f ("file")
while (f)
    Point p = read_point (f)
    cout << reduce (p)