Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C structure pointer dereferencing speed

I have a question regarding the speed of pointer dereferencing. I have a structure like so:

typedef struct _TD_RECT TD_RECT;
struct _TD_RECT {
  double left;
  double top;
  double right;
  double bottom;
};

My question is, which of these would be faster and why?


CASE 1:

TD_RECT *pRect;
...
for(i = 0; i < m; i++)
{
   if(p[i].x < pRect->left) ...
   if(p[i].x > pRect->right) ...
   if(p[i].y < pRect->top) ...
   if(p[i].y > pRect->bottom) ...
}

CASE 2:

TD_RECT *pRect;
double left = pRect->left;
double top = pRect->top;
double right = pRect->right;
double bottom = pRect->bottom;
...
for(i = 0; i < m; i++)
{
   if(p[i].x < left) ...
   if(p[i].x > right) ...
   if(p[i].y < top) ...
   if(p[i].y > bottom) ...
}

So in case 1, the loop is directly dereferencing the pRect pointer to obtain the comparison values. In case 2, new values were made on the function's local space (on the stack) and the values were copied from the pRect to the local variables. Through a loop there will be many comparisons.

In my mind, they would be equally slow, because the local variable is also a memory reference on the stack, but I'm not sure...

Also, would it be better to keep referencing p[] by index, or increment p by one element and dereference it directly without an index.

Any ideas? Thanks :)

like image 370
oldSkool Avatar asked Oct 21 '10 11:10

oldSkool


People also ask

Is dereferencing a pointer expensive?

Dereferencing, when translated into machine code, can mean different things depending on what you do with the dereferenced object. Accessing a single member of a class through a pointer is typically cheap.

What is pointer dereferencing in C?

Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.

What does the dereference operator (*) do?

In computer programming, a dereference operator, also known as an indirection operator, operates on a pointer variable. It returns the location value, or l-value in memory pointed to by the variable's value. In the C programming language, the deference operator is denoted with an asterisk (*).

Which C operator is used to dereference a pointer?

The unary operator * is used to declare a pointer and the unary operator & is used to dereference the pointer.. In both cases, the operator is “unary” because it acts upon a single operand to produce a new value.


2 Answers

You'll probably find it won't make a difference with modern compilers. Most of them would probably perform common subexpresion elimination of the expressions that don't change within the loop. It's not wise to assume that there's a simple one-to-one mapping between your C statements and assembly code. I've seen gcc pump out code that would put my assembler skills to shame.

But this is neither a C nor C++ question since the ISO standard doesn't mandate how it's done. The best way to check for sure is to generate the assembler code with something like gcc -S and examine the two cases in detail.

You'll also get more return on your investment if you steer away from this sort of micro-optimisation and concentrate more on the macro level, such as algorithm selection and such.

And, as with all optimisation questions, measure, don't guess! There are too many variables which can affect it, so you should be benchmarking different approaches in the target environment, and with realistic data.

like image 96
paxdiablo Avatar answered Oct 14 '22 17:10

paxdiablo


It is not likely to be a hugely performance critical difference. You could profile doing each option multiple times and see. Ensure you have your compiler optimisations set in the test.

With regards to storing the doubles, you might get some performance hit by using const. How big is your array?

With regards to using pointer arithmetic, this can be faster, yes.

You can instantly optimise if you know left < right in your rect (surely it must be). If x < left it can't also be > right so you can put in an "else".

Your big optimisation, if there is one, would come from not having to loop through all the items in your array and not have to perform 4 checks on all of them.

For example, if you indexed or sorted your array on x and y, you would be able, using binary search, to find all values that have x < left and loop through just those.

like image 43
CashCow Avatar answered Oct 14 '22 18:10

CashCow