Optimizing parameter input for functions
I have a function that has a large number if individual input parameters, the function is also run hundreds of millions of times during the program.
If i wanted to optimize this function, should I create a new da开发者_JAVA百科ta structure that holds all the input parameters and pass it to the function by reference instead of passing each parameter individually to the function? Or would it not matter because the compiler is smart enough to deal wit this in an even more efficient manner?
In general, it's much better to pass a data structure that contains your variables. This isn't pretty to look at or use:
void f(int a, int b, int c, int d, int e, int f)
{
// do stuff
}
This is much nicer:
void f(Params p)
{
// do stuff with p
}
You may want to do pass by reference, so the compiler can just pass a reference to the object, and not copy the entire data structure. As a real example:
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);
}
It would be better if encapsulated our (x, y, z) into a data structure though:
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);
}
Much cleaner code, and you get the added bonus that it could* perform better (*Depending on how smart your compiler is at optimizing either version).
Obviously this could vary wildly depending on what you're actually trying to accomplish, but if you have several (4+) variables that have a similar usage in a certain context, it may be better to just pass it in a data structure.
Are the arguments mostly constant, or do most of them change on every call? You don't want to evaluate arguments many times if you could only do them once.
Keep in mind what the compiler does with arguments.
It evaluates each one and pushes it on the stack. Then the function is entered, and it refers to those arguments by their offset in the stack. So it is basically the same as if you put the arguments into a block and passed the block. However, if you build the block yourself, you may be able to re-use old values and only evaluate the ones you know have changed.
In any case, you really have to look at how much work goes on inside the function relative to the time spent passing arguments to it. It's irrelevant that you're calling it 10^8 times without knowing over what overall time span. That could be 10ns per call, or 10ms per call. If the latter, nearly all the time is spent inside the function, so it probably doesn't make much difference how you call it.
精彩评论