Thread: Speed of pointers vs. speed of arrays/structs

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    147

    Speed of pointers vs. speed of arrays/structs

    What's faster, pointers manipulation or subscripting with arrays/structs?

    Also, I have read that if having lots of global vars, it is better to join them in a typedef struct and create a global register var pointer to them. Something like this:

    Code:
    typedef struct {
    int a
    int b
    char s[10];
    ...
    } t_data;
    
    register t_data *p
    Access global data as p->a, p->b, etc..... This look liike faster but why? is this trick speed improvement.
    Thx.
    FS

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Accessing anything through a pointer is slowing things down.

    Global variables are generally not optimized to the same level as local variables (e.g. the compiler will only allow local variables to stay in registers across function calls, global variables must always be reloaded after a function call [unless the code in the called function is clearly and obviously NOT accessing the global variable(s) in question]).

    I doubt having one global pointer is any better than having a global struct.

    Having a local variable (or parameter) that is passed from function to function may help a bit - but then pointer references also have to be reloaded when crossing function calls.

    The only way to determine of something is faster or not is by doing performance measurements.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by Kempelen View Post
    What's faster, pointers manipulation or subscripting with arrays/structs?
    Pointer notation vs array notation is going to be the same speed, or should be anyway.

    Quote Originally Posted by Kempelen View Post
    Also, I have read that if having lots of global vars, it is better to join them in a typedef struct and create a global register var pointer to them.
    For the sake of speed, no this is slower. Struct members are accessed by an offset to the base of the struct, which acts in effect as a sort of array of unequally-sized and arbitrary types.

    The fastest way for code is possibly to declare everything global for a number of reasons, although matsp pointed out how this could be slower if the compiler knows how to optimize things properly. This is known, however, to be a horrible practice that leads to all kinds of issues. For one, it's hard to write the code, but maintaining it and updating it is a nightmare, especially if you haven't written it to begin with and you're tasked with such a horrible assignment. You have to decide at what price you want speed and what price you want readability, maintainability, and portability, etc. etc..

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MacGyver View Post
    Pointer notation vs array notation is going to be the same speed, or should be anyway.
    Accessing through pointers is slower than through array notation, in terms of raw speed.
    In an application today, the speed difference is so subtle you won't notice anything.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by Elysia View Post
    Accessing through pointers is slower than through array notation, in terms of raw speed.
    In an application today, the speed difference is so subtle you won't notice anything.
    I was referring to something like this:

    • *(buffer + 1)
    • buffer[1]


    Between the two, there is no real difference.

    Now if buffer is a "real" pointer vs a "real" array, there is a difference, but the notation itself should mean nothing.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Hmm, yes, I guess you're right
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Accessing through pointers is slower than through array notation, in terms of raw speed.
    I recall Patterson and Hennessy stating the opposite, at least when routine optimisations are not applied, though the details are long forgotten with my book currently with my girlfriend, who is overseas.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    I found the trick here, in the web of cprogramming.com:
    http://www.cprogramming.com/tips/sho...ount=30&page=0

    what about using a register for store the pointer of a global struct:

    Code:
    register GlobalVars *g asm(\\"a4\\");
    I found this link too: http://gcc.gnu.org/onlinedocs/gcc-4....-Reg-Vars.html

    I would like to test by myself if this provoke a speed improvement in my program, but using MINGW for windows I don't know how to do it. I get this error for the above line:

    Code:
    syntax error before asm
    Anyone knows how to do it for windows/intel plataform. Also "a4" is the name of the register to use. Any recomendation/tip on what register to use?

    Want to test it. theory is good, but in speed issues I think it is better to test by myselg it in order to make conclusions. I will post my results

    thx

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, that is more to the point that in some architectures (68000 in this example) allows you to store a pointer in a global register. For the most cases in a modern compiler, however, it just gives the compiler one less register to work with, and the compilers these days are pretty darn good at figuring out what to put in a register, and what to not put in a register.

    On x86, this would almost certainly cause more problems than it solves as there are only a few (7 at the very most) freely usable registers in x86. Even if almost every line is accessing the global variable it's unlikely to give any enormous benefits then either, since the compiler will be able to load the global pointer at the beginning of the code and then operate on it from then on.

    Compilers these days are pretty good at assigning registers the right way, and given a choice, I'd prefer to use the compiler to figure out which register to use when.

    However, it does work to use global register variables in gcc:
    Code:
    #include <stdio.h>
    
    register int x asm("ebx");
    
    
    int main()
    {
      x = 7;
      printf("x = %d\n", x);
      return 0;
    }
    compiles OK with gcc-mingw 3.4.2, and studying the assembler code, it puts the value 7 in ebx, and pushes ebx to printf.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    I use pass structs by pointers. That can save up some space.Not sure if this is efficient though.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by broli86 View Post
    I use pass structs by pointers. That can save up some space.Not sure if this is efficient though.
    There is a trade-off between the dereferencing the pointer and not copying the structure vs. copying the structure and being able to directly access the data.

    In general passing as a pointer is the better choice. The bigger the struct is, the bigger the benefit.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Kempelen View Post
    Code:
    register t_data *p
    Don't use the register keyword EVER! In almost all compilers used nowdays it does nothing whatsoever, and in the ones where is doesn't do nothing you will almost cetainly only make things worse - even if you consider yourself an expert programmer!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by iMalc View Post
    Don't use the register keyword EVER! In almost all compilers used nowdays it does nothing whatsoever, and in the ones where is doesn't do nothing you will almost cetainly only make things worse - even if you consider yourself an expert programmer!
    I agree with that - and I'm not just "me tooing" here, as I just didn't explain that as clearly in my post above:
    Compilers these days are pretty good at assigning registers the right way, and given a choice, I'd prefer to use the compiler to figure out which register to use when.
    If the compiler obliges your register keyword, it leaves one less register to play with for other purposes - again, the compiler knows better than me what goes in which register and when. [And I usually have a pretty darn good idea of what the compiler does with the code I write].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Quote Originally Posted by matsp View Post
    Well, that is more to the point that in some architectures (68000 in this example) allows you to store a pointer in a global register. For the most cases in a modern compiler, however, it just gives the compiler one less register to work with, and the compilers these days are pretty darn good at figuring out what to put in a register, and what to not put in a register.

    On x86, this would almost certainly cause more problems than it solves as there are only a few (7 at the very most) freely usable registers in x86. Even if almost every line is accessing the global variable it's unlikely to give any enormous benefits then either, since the compiler will be able to load the global pointer at the beginning of the code and then operate on it from then on.

    Compilers these days are pretty good at assigning registers the right way, and given a choice, I'd prefer to use the compiler to figure out which register to use when.

    However, it does work to use global register variables in gcc:
    Code:
    #include <stdio.h>
    
    register int x asm("ebx");
    
    
    int main()
    {
      x = 7;
      printf("x = %d\n", x);
      return 0;
    }
    compiles OK with gcc-mingw 3.4.2, and studying the assembler code, it puts the value 7 in ebx, and pushes ebx to printf.

    --
    Mats
    I don't know why, but mingw get an error "syntax error before asm", any idea?

  15. #15
    Registered User
    Join Date
    Feb 2008
    Posts
    147
    Quote Originally Posted by iMalc View Post
    Don't use the register keyword EVER
    In speed issues, I have learn the hard way with a few years of experience that the best is to test it. Althought maybe I will not get anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. moving pointers to pointers
    By Benzakhar in forum C++ Programming
    Replies: 9
    Last Post: 12-27-2003, 08:30 AM
  3. pointers to pointers within structs
    By Lord_azrael99 in forum C Programming
    Replies: 2
    Last Post: 08-28-2003, 04:29 AM
  4. Pointers pointers pointers....
    By G'n'R in forum C Programming
    Replies: 11
    Last Post: 11-02-2001, 02:02 AM
  5. Pointers pointers pointers...
    By SMurf in forum C Programming
    Replies: 8
    Last Post: 10-23-2001, 04:55 PM