如何使我的动态数组或向量以与标准数组相似的速度运行?C++; 我仍然缺乏C++经验,我正试图编写和代码来精确地添加数字。这是一些有限差分软件的dll插件,在运行过程中,代码会被调用数百万次。我想写一个函数,其中可以传入任意数量的参数,并返回总和。我的代码如下所示: #include <cstdarg> double SumFunction(int numArgs, ...){ // this allows me to pass any number // of arguments to my function. va_list args; va_start(args,numArgs); //necessary prerequisites for using cstdarg double myarray[10]; for (int i = 0; i < numArgs; i++) { myarray[i] = va_arg(args,double); } // I imagine this is sloppy code; however i cannot create // myarray{numArgs] because numArgs is not a const int. sum(myarray); // The actual method of addition is not relevant here, but //for more complicated methods, I need to put the summation // terms in a list. vector<double> vec(numArgs); // instead, place all values in a vector for (int i = 0; i < numArgs; i++) { vec.at(i) = va_arg(args,double); } sum(vec); //This would be passed by reference, of course. The function sum // doesn't actually exist, it would all be contained within the // current function. This is method is twice as slow as placing //all the values in the static array. double *vec; vec = new double[numArgs]; for (int i = 0; i < (numArgs); i++) { vec[i] = va_arg(args,double); } sum(vec); // Again half of the speed of using a standard array and // increasing in magnitude for every extra dynamic array! delete[] vec; va_end(args); } #包括 双求和函数(int numArgs,…){//这允许我传递任何数字 //我的函数的参数。 va_列表参数; va_start(args,numArgs);//使用cstdarg的必要先决条件 双myarray[10]; 对于(int i=0;i时,优化器必须考虑重新定位是可能的。额外的间接行为

如何使我的动态数组或向量以与标准数组相似的速度运行?C++; 我仍然缺乏C++经验,我正试图编写和代码来精确地添加数字。这是一些有限差分软件的dll插件,在运行过程中,代码会被调用数百万次。我想写一个函数,其中可以传入任意数量的参数,并返回总和。我的代码如下所示: #include <cstdarg> double SumFunction(int numArgs, ...){ // this allows me to pass any number // of arguments to my function. va_list args; va_start(args,numArgs); //necessary prerequisites for using cstdarg double myarray[10]; for (int i = 0; i < numArgs; i++) { myarray[i] = va_arg(args,double); } // I imagine this is sloppy code; however i cannot create // myarray{numArgs] because numArgs is not a const int. sum(myarray); // The actual method of addition is not relevant here, but //for more complicated methods, I need to put the summation // terms in a list. vector<double> vec(numArgs); // instead, place all values in a vector for (int i = 0; i < numArgs; i++) { vec.at(i) = va_arg(args,double); } sum(vec); //This would be passed by reference, of course. The function sum // doesn't actually exist, it would all be contained within the // current function. This is method is twice as slow as placing //all the values in the static array. double *vec; vec = new double[numArgs]; for (int i = 0; i < (numArgs); i++) { vec[i] = va_arg(args,double); } sum(vec); // Again half of the speed of using a standard array and // increasing in magnitude for every extra dynamic array! delete[] vec; va_end(args); } #包括 双求和函数(int numArgs,…){//这允许我传递任何数字 //我的函数的参数。 va_列表参数; va_start(args,numArgs);//使用cstdarg的必要先决条件 双myarray[10]; 对于(int i=0;i时,优化器必须考虑重新定位是可能的。额外的间接行为,c++,arrays,optimization,vector,C++,Arrays,Optimization,Vector,换句话说,代码 v[index] += value; 例如,其中v是一个std::vector展开为 int *p = v._begin + index; *p += value; i、 e.从vector中,首先需要获取字段\u begin(其中包含内存中内容的起始位置),然后应用索引,然后取消引用以获取值并对其进行变异 如果在循环中对向量元素执行计算的代码调用任何未知的非内联代码,则优化器将被迫假设未知代码可能会变异向量的\u begin字段,这将需要对每个元素执行两个间接步骤 (注意:

换句话说,代码

v[index] += value;
例如,其中
v
是一个
std::vector
展开为

int *p = v._begin + index;
*p += value;
i、 e.从vector中,首先需要获取字段
\u begin
(其中包含内存中内容的起始位置),然后应用索引,然后取消引用以获取值并对其进行变异

如果在循环中对向量元素执行计算的代码调用任何未知的非内联代码,则优化器将被迫假设未知代码可能会变异向量的
\u begin
字段,这将需要对每个元素执行两个间接步骤

(注意:向量通过
cost std::vector&
引用传递是完全不相关的:
const
引用并不意味着向量是
const
,而是简单地限制了使用该引用允许的操作;外部代码可以有一个非
const
引用访问向量和
const
ness也可以合法地丢弃…
const
引用的ness基本上被优化器忽略

删除此额外查找的一种方法(如果您知道在计算过程中未调整向量的大小)是将此地址缓存在本地地址中,并使用该地址而不是向量运算符来访问元素:

int *p = &v[0];
for (int i=0,n=v.size(); i<n; i++) {
    /// use p[i] instead of v[i]
}
int*p=&v[0];

对于(int i=0,n=v.size();i加快代码速度的一种方法是在调用之间重用动态数组或向量,这样可以避免每次调用该函数时产生内存分配和释放的开销

例如,在函数外部将这些变量声明为全局变量或在某个类中声明为成员变量。为了便于解释,我只将它们声明为全局变量:

double* sumArray = NULL;
int sumArraySize = 0;
在sum函数中,检查数组是否存在,如果不存在,则分配它,必要时调整大小:

double SumFunction(int numArgs, ...){ // this allows me to pass any number 
                                  // of arguments to my function.
    va_list args;
    va_start(args,numArgs); //necessary prerequisites for using cstdarg

    // if the array has already been allocated, check if it is large enough and delete if not:
    if((sumArray != NULL) && (numArgs > sumArraySize))
    {
        delete[] sumArray;
        sumArray = NULL;
    }

    // allocate the array, but only if necessary:
    if(sumArray == NULL)
    {
        sumArray = new double[numArgs];
        sumArraySize = numArgs;
    }

    double *vec = sumArray;   // set to your array, reusable between calls
    for (int i = 0; i < (numArgs); i++) {
        vec[i] = va_arg(args,double);
    }
    sum(vec, numArgs); // you will need to pass the array size

    va_end(args);

    // note no array deallocation
}
您可以对向量采取类似的(更简单/更干净)方法,如果向量不存在,则第一次分配它,如果存在,则使用numArgs对其调用resize()。

假设“所需的最大存储空间”在10-50之间,我认为使用本地数组是非常好的

使用
vector
将使用
3*sizeof(*T)
(至少)来跟踪向量的内容。因此,如果我们将其与
double arr[10];
数组进行比较,那么在相同大小的堆栈中,这就多了7个元素(或32位构建中的8.5个元素)。但是您还需要调用
new
,它需要一个size参数。因此,这至少占用了堆栈空间的一个元素,更可能是2-3个元素,而且
new
的实现可能并不简单,因此需要进一步的调用,这会占用更多的堆栈空间


如果您“不知道”元素的数量,并且需要处理相当多的元素,则使用混合解决方案,其中您有一个基于小堆栈的本地数组,如果
numargs>small_size
使用vector,然后传递
vec.data()<代码>函数>代码>和/代码> ./P>请整理缩进,确保您正在构建具有完全优化、C++结构(特别是MSVC)的C++代码。有破坏矢量化的调试检查,并且确实会减慢速度。也请发布构建标志。谢谢米哈伊尔。我不知道你在寻找哪些优化,所以我只是从MSVC复制并粘贴了它们:'/Zi/nologo/W3/WX/Ox/Ob2/Oi/Ot/Oy-/GL/D“WIN32”/D“NDEBUG”/D“WINDOWS”/D“\u USRDLL”/D“MODELSIMPLE\u导出”/D“_windell”/D“_UNICODE”/D“UNICODE”/Gm-/EHsc/GS/Gy/fp:precise/Zc:wchar\u t/Zc:forScope/fp“Release\modelsimple005.pch”/Fa“Release\”/Fo“Release\”/Fd“Release\vc100.pdb”/Gd/analyze-/error
void freeSumArray()
{
    if(sumArray != NULL)
    {
        delete[] sumArray;
        sumArray = NULL;
        sumArraySize = 0;
    }
}