开发者

how to create variable shortcut

开发者 https://www.devze.com 2023-01-30 02:28 出处:网络
Suppose I need to create complex math formula, for example double f(double array1[100], double array2[100])

Suppose I need to create complex math formula, for example

double f(double array1[100], double array2[100])
{
    double z = array1[21] * array2[3] + array[10];
    double q = array1[21] * array1[30] / array1[10];
    return array1[1] * z * q;
}

or more complex. My solution is to create intermediate variables like:

double f(double array1[100], double array2[100])
{
    double energy = array1[21];
    double mass   = array2[3];
    double speed = array[10];
    double z = energy * mass + speed;
    double q = energy * array[30] / speed;
    return array1[1] * z * q;
}

the problem is that I don't really need these new variable and I don't want to waste memory or increase time to call the function. So now I'm using const for every intermediate variable so maybe the compila开发者_JAVA技巧tor is more prone to optimize it. But maybe is it better to use references?


  1. Design your application in a way that doesn't prevent fast code.
  2. Write your code so that that it is easily readable and maintainable.
  3. Make it working correctly.
  4. Test it to find out whether it is too slow.
  5. If so, profile it to see where it spends most of its time.
  6. Look into these areas to see if performance can be improved by improving the algorithms used.
  7. If all else fails (and only then), start tweaking code in the manner you're asking for, in places profiling have shown to be relevant to the applications overall-performance. This will usually be very few spots.


gcc-llvm with standard optimization: Results are identical ignoring instruction reordering

define double @_Z1fPdS_(double* nocapture %array1, double* nocapture %array2) nounwind readonly {
entry:
  %0 = getelementptr inbounds double* %array1, i64 21 ; <double*> [#uses=1]
  %1 = load double* %0, align 8                   ; <double> [#uses=2]
  %2 = getelementptr inbounds double* %array2, i64 3 ; <double*> [#uses=1]
  %3 = load double* %2, align 8                   ; <double> [#uses=1]
  %4 = fmul double %1, %3                         ; <double> [#uses=1]
  %5 = getelementptr inbounds double* %array1, i64 10 ; <double*> [#uses=1]
  %6 = load double* %5, align 8                   ; <double> [#uses=2]
  %7 = fadd double %4, %6                         ; <double> [#uses=1]
  %8 = getelementptr inbounds double* %array1, i64 30 ; <double*> [#uses=1]
  %9 = load double* %8, align 8                   ; <double> [#uses=1]
  %10 = fmul double %1, %9                        ; <double> [#uses=1]
  %11 = fdiv double %10, %6                       ; <double> [#uses=1]
  %12 = getelementptr inbounds double* %array1, i64 1 ; <double*> [#uses=1]
  %13 = load double* %12, align 8                 ; <double> [#uses=1]
  %14 = fmul double %13, %7                       ; <double> [#uses=1]
  %15 = fmul double %14, %11                      ; <double> [#uses=1]
  ret double %15
}

define double @_Z2f2PdS_(double* nocapture %array1, double* nocapture %array2) nounwind readonly {
entry:
  %0 = getelementptr inbounds double* %array1, i64 21 ; <double*> [#uses=1]
  %1 = load double* %0, align 8                   ; <double> [#uses=2]
  %2 = getelementptr inbounds double* %array2, i64 3 ; <double*> [#uses=1]
  %3 = load double* %2, align 8                   ; <double> [#uses=1]
  %4 = getelementptr inbounds double* %array1, i64 10 ; <double*> [#uses=1]
  %5 = load double* %4, align 8                   ; <double> [#uses=2]
  %6 = fmul double %1, %3                         ; <double> [#uses=1]
  %7 = fadd double %6, %5                         ; <double> [#uses=1]
  %8 = getelementptr inbounds double* %array1, i64 30 ; <double*> [#uses=1]
  %9 = load double* %8, align 8                   ; <double> [#uses=1]
  %10 = fmul double %9, %1                        ; <double> [#uses=1]
  %11 = fdiv double %10, %5                       ; <double> [#uses=1]
  %12 = getelementptr inbounds double* %array1, i64 1 ; <double*> [#uses=1]
  %13 = load double* %12, align 8                 ; <double> [#uses=1]
  %14 = fmul double %13, %7                       ; <double> [#uses=1]
  %15 = fmul double %14, %11                      ; <double> [#uses=1]
  ret double %15
}


I'd start passing the two input array by const pointer or const reference.

I don't think it is a great idea have a function like your example, I don't know if it is just an example or real code. I think the difference in performance are very minimal and it is much better create a code easy to read.

To answer to your question: avoid temporary object when possible, so use reference. Use const keyword if logically make sense that a variable is const and not for performance reason.

Improve the speed just after profiling.


With any decent compiler I very much doubt it matters.

For local variables where you don't take the address of the variable anywhere the compiler will be able to see that they are only used within that function as "temporary" values and optimise them out. They almost certanly won't take up any memory or generate any code that wouldn't have been needed anyway.

I doubt that declaring them const will make any difference, and if you make them a reference then they have to be a reference to "something" anyway.

To be honest I wouldn't worry about it at all, just write whatever code seems most natural and let the compiler do it's job.


If you use multiple variables on your function foreach call you make to the method you need to alloc the space in stack for them, and foreach use you may need to go to the memory to get the values, making multiple variables more inefficient. Probably the compiler is smart enough to avoid unnecessary memory reads and writes, but if you don't need the extra variables dont use it, but if your code is more explicit with the use of multiple variables use them because probably the compiler makes everything smoth.


I would tackle this slightly differently.

If you want to make it more readable why not define some constants

static const unsigned int energy = 21;
static const unsigned int speed = 10;
static const unsigned int mass = 3;

double z = array1[energy] * array2[mass] + array[speed];   
double q = array1[energy] * array1[30] / array1[speed]; 
return array1[1] * z * q;   

The index variables can be defined globally.

What do the values at 1 and 30 represent?

I see that there is another variable array that you don't define.

0

精彩评论

暂无评论...
验证码 换一张
取 消