简体   繁体   中英

Optimizing C code, Horner's polynomial evaluation

I'm trying to learn how to optimize code (I'm also learning C), and in one of my books there's a problem for optimizing Horner's method for evaluation polynomials. I'm a little lost on how to approach the problem. I'm not great at recognizing what needs optimizing.

Any advice on how to make this function run faster would be appreciated.

Thanks

 double polyh(double a[], double x, int degree) {
        long int i;
        double result = a[degree];
        for (i = degree-1; i >= 0; i--) 
            result = a[i] + x*result;
        return result;
    }

You really need to profile your code to test whether proposed optimizations really help. For example, it may be the case that declaring i as long int rather than int slows the function on your machine, but on the other hand it may make no difference on your machine but might make a difference on others, etc. Anyway, there's no reason to declare i a long int when degree is an int , so changing it probably won't hurt. (But still profile!)

Horner's rule is supposedly optimal in terms of the number of multiplies and adds required to evaluate a polynomial, so I don't see much you can do with it. One thing that might help (profile!) is changing the test i>=0 to i!=0 . Of course, then the loop doesn't run enough times, so you'll have to add a line below the loop to take care of the final case.

Alternatively you could use a do { ... } while (--i) construct. (Or is it do { ... } while (i--) ? You figure it out.)

You might not even need i , but using degree instead will likely not save an observable amount of time and will make the code harder to debug, so it's not worth it.

Another thing that might help (I doubt it, but profile!) is breaking up the arithmetic expression inside the loop and playing around with order, like

for (...) {
  result *= x;
  result += a[i];
}

which may reduce the need for temporary variables/registers. Try it out.

Some suggestion:

  1. You may use int instead of long int for looping index.

Almost certainly the problem is inviting you to conjecture on the values of a . If that vector is mostly zeros, then you'll go faster (by doing fewer double multiplications, which will be the clear bottleneck on most machines) by computing only the values of a[i] * x^i for a[i] != 0 . In turn the x^i values can be computed by careful repeated squaring, preserving intermediate terms so that you never compute the same partial power more than once. See the Wikipedia article if you've never implemented repeated squaring.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM