Visual c++ 优化函数的参数输入

Visual c++ 优化函数的参数输入,visual-c++,function,optimization,parameter-passing,Visual C++,Function,Optimization,Parameter Passing,我有一个函数,它有大量的输入参数,这个函数在程序中也运行了数亿次 如果我想优化这个函数,我是否应该创建一个新的数据结构来保存所有输入参数,并通过引用将其传递给函数,而不是将每个参数单独传递给函数?或者这不重要,因为编译器足够聪明,能够以更有效的方式处理这个问题吗?一般来说,传递包含变量的数据结构要好得多。这看起来或使用起来都不好看: void f(int a, int b, int c, int d, int e, int f) { // do stuff } 这要好多了: void f

我有一个函数,它有大量的输入参数,这个函数在程序中也运行了数亿次


如果我想优化这个函数,我是否应该创建一个新的数据结构来保存所有输入参数,并通过引用将其传递给函数,而不是将每个参数单独传递给函数?或者这不重要,因为编译器足够聪明,能够以更有效的方式处理这个问题吗?

一般来说,传递包含变量的数据结构要好得多。这看起来或使用起来都不好看:

void f(int a, int b, int c, int d, int e, int f)
{
   // do stuff
}
这要好多了:

void f(Params p)
{
  // do stuff with p
}
您可能希望按引用传递,因此编译器可以只传递对对象的引用,而不复制整个数据结构。 作为一个真实的例子:

double distance(double x1, double y1, double z1, double x2, double y2, double z2)
{
    double dx = x1 - x2;
    double dy = y1 - y2;
    double dz = z1 - z2;

    return sqrt(dx*dx + dy*dy + dz*dz);
}
如果将我们的(x,y,z)封装到数据结构中会更好:

struct Point
{
    double x;
    double y;
    double z;
};

double distance(const Point &p1, const Point &p2)
{
    double dx = p1.x - p2.x;
    double dy = p1.y - p2.y;
    double dz = p1.z - p2.z;

    return sqrt(dx*dx + dy*dy + dz*dz);
}
更干净的代码,您还可以获得额外的好处,即它可以*执行得更好(*取决于您的编译器在优化任何一个版本时有多聪明)


显然,这可能会因您实际要完成的任务而发生很大变化,但如果您有几个(4+)变量在特定上下文中具有类似的用法,则最好只在数据结构中传递它。

一般来说,传递包含您的变量的数据结构要好得多。这看起来或使用起来都不好看:

void f(int a, int b, int c, int d, int e, int f)
{
   // do stuff
}
这要好多了:

void f(Params p)
{
  // do stuff with p
}
您可能希望按引用传递,因此编译器可以只传递对对象的引用,而不复制整个数据结构。 作为一个真实的例子:

double distance(double x1, double y1, double z1, double x2, double y2, double z2)
{
    double dx = x1 - x2;
    double dy = y1 - y2;
    double dz = z1 - z2;

    return sqrt(dx*dx + dy*dy + dz*dz);
}
如果将我们的(x,y,z)封装到数据结构中会更好:

struct Point
{
    double x;
    double y;
    double z;
};

double distance(const Point &p1, const Point &p2)
{
    double dx = p1.x - p2.x;
    double dy = p1.y - p2.y;
    double dz = p1.z - p2.z;

    return sqrt(dx*dx + dy*dy + dz*dz);
}
更干净的代码,您还可以获得额外的好处,即它可以*执行得更好(*取决于您的编译器在优化任何一个版本时有多聪明)


显然,这可能会因您实际要完成的任务而有很大的不同,但是如果您有几个(4+)变量在特定上下文中具有类似的用法,则最好将其传递到数据结构中。

参数大部分是常量,还是在每次调用时都会发生变化?如果只能对参数进行一次计算,则不希望对参数进行多次计算

请记住编译器是如何处理参数的

它计算每个值并将其推送到堆栈上。然后,函数被输入,它根据这些参数在堆栈中的偏移量引用它们。因此,这基本上与将参数放入一个块并传递该块是一样的。但是,如果您自己构建块,您可能能够重用旧值,并且只评估您知道已更改的值


在任何情况下,您都必须查看函数内部所做的工作相对于向其传递参数所花费的时间。在不知道整个时间跨度的情况下,调用它10^8次是无关紧要的。这可能是每次通话10纳秒,或每次通话10毫秒。如果是后者,则几乎所有的时间都花在函数内部,因此调用它的方式可能没有多大区别。

参数大部分是常量,还是每次调用时都会发生变化?如果只能对参数进行一次计算,则不希望对参数进行多次计算

请记住编译器是如何处理参数的

它计算每个值并将其推送到堆栈上。然后,函数被输入,它根据这些参数在堆栈中的偏移量引用它们。因此,这基本上与将参数放入一个块并传递该块是一样的。但是,如果您自己构建块,您可能能够重用旧值,并且只评估您知道已更改的值


在任何情况下,您都必须查看函数内部所做的工作相对于向其传递参数所花费的时间。在不知道整个时间跨度的情况下,调用它10^8次是无关紧要的。这可能是每次通话10纳秒,或每次通话10毫秒。如果是后者,那么几乎所有的时间都花在函数内部,因此调用它的方式可能没有多大区别。

如果编译器没有内联这样的函数,我会非常惊讶。它是递归的吗?不,不是递归的,只是在一个巨大的5嵌套循环中…如果编译器没有内联这样一个函数,我会非常惊讶。它是递归的吗?不,不是递归的,只是在一个巨大的5嵌套循环中…嗯…96个变量怎么样?该函数是一个与数学相关的函数。96个变量表示您可能做错了什么。你到底在做什么?变量来自左、右和中间,并根据函数所在的大量循环进行选择。不过,总的来说,我应该使用一个结构?你能告诉我们你到底想完成什么吗?如果您给我们举个例子,可能有一种简单的方法可以重构代码。在处理大量变量时,我说“一般”,但在某些情况下重构代码可能更好。嗯……96个变量怎么样?该函数是一个与数学相关的函数。96个变量表示您可能做错了什么。你到底在做什么?变量来自左、右和中间,并根据函数所在的大量循环进行选择。不过,总的来说,我应该使用一个结构?你能告诉我们你到底想完成什么吗?如果您给我们举个例子,可能有一种简单的方法可以重构代码。在处理大量变量时,我说“一般”,但在某些情况下,重构代码可能更好。