Thread: When to inline your *tors

  1. #31
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Angus View Post
    Still, I don't believe GNU does LTO, and the onus for optimization wrt inlining is on the programmer.
    And even if gcc does, there are plenty of other compilers that DOESN'T, so it's safer to assume that the compiler can't do that unless you are only writing code that is ever compiled in one compiler.

    However, I think the constructor/destructor is not the commonly key point of performance - supposedly your object DOES something - and commonly that is where the key performance is. Of course, there are situations where creating & destroying the object is very much what you DO with the object, but it shouldn't be the norm.

    --
    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.

  2. #32
    Kung Fu Kitty Angus's Avatar
    Join Date
    Oct 2008
    Location
    Montreal, Canada
    Posts
    115
    Quote Originally Posted by matsp View Post
    However, I think the constructor/destructor is not the commonly key point of performance - supposedly your object DOES something - and commonly that is where the key performance is. Of course, there are situations where creating & destroying the object is very much what you DO with the object, but it shouldn't be the norm.
    In many cases, I agree. Probably even most cases. Maybe even 99.999% of the cases. However, once in a while those *tors are going to be called a heck of a lot more than you expect, such as in the case of a large array, or even STL's vector class, with its resize()s and push_back()s. Those cause an awful lot more *tor calls than many people would think, in which case you might want to be shaving off every last cycle you could from construction and destruction.

  3. #33
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sure, there are situations where constructors are called often, for good reasons. However, in some of the cases you make examples of (vectors resizing) would be solved by not storing the object directly, but storing a pointer/reference to the actual object. That way, there is a "no cost" of copying to a larger vector. Sure, there are cases when that isn't the right thing either.

    But as a rule, constructors are less important to inline than other functions. And in ALL cases, the choice to inline should be based on facts and profiling information, not a guess.

    --
    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.

  4. #34
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You don't choose to give the inline hint except after profiling indicates lack of it being inlined for you is a significant performance problem. That's what it comes down to, because it's just too complex. Inlining always has the potential to slow things down as well. The function your constructor gets or dosn't get inlined into might be just small enough to fit in the instruction cache without the constructor inlining for example. You basically need to trust the compiler. Treat it as knowing best until proven otherwise (innocent until proven guilty).
    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"

  5. #35
    Kung Fu Kitty Angus's Avatar
    Join Date
    Oct 2008
    Location
    Montreal, Canada
    Posts
    115
    Quote Originally Posted by matsp View Post
    But as a rule, constructors are less important to inline than other functions. And in ALL cases, the choice to inline should be based on facts and profiling information, not a guess.
    No, not ALL cases. In many cases your guess can be educated. For instance,
    Code:
    class _class {
    protected:
        int i;
    public:
        int GetI() const {
              return i;
         }
    };
    You've got every reason to keep GetI() inline. Not only will it take fewer cycles, but it'll make smaller code, because you eliminate the parameter-passing instructions, the jump instruction, the return instruction, and the return value instruction. No need to profile here. These principles similarly apply to *tors.

  6. #36
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    But are you positive that your accessors, simple constructors, and destructors are performance bottlenecks? If you're trying to meet time constraints, you can do much more than just inline stuff. Pick a better algorithm or revise the data with which you work. The point is not to inline just because and that's exactly what you seem to be going after.

  7. #37
    Kung Fu Kitty Angus's Avatar
    Join Date
    Oct 2008
    Location
    Montreal, Canada
    Posts
    115
    Quote Originally Posted by citizen View Post
    But are you positive that your accessors, simple constructors, and destructors are performance bottlenecks? If you're trying to meet time constraints, you can do much more than just inline stuff. Pick a better algorithm or revise the data with which you work. The point is not to inline just because and that's exactly what you seem to be going after.
    Why not? It is the topic of my OP.

  8. #38
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Is that your way of saying you'll ignore me? That wasn't a good response to the question I asked you. Are you sure those things are bottlenecks?

  9. #39
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Angus View Post
    Why not? It is the topic of my OP.
    Yes, but several times in this post we have commented on "it is not, generally, a good idea to inline without good reason". Yes, there are cases (getters, setters with simple functions and simple data types) where inlining it is a natural.

    However, not only is inlining sometimes detrimental to performance. It has a completely different-side effect too.

    Let's say we have a scenario where we use a .DLL to implement a class. In version one, we implement the class like this:
    Code:
    class X
    {
       int array[100];
    public:
       int getX(int index) { return array[index]; }
    ...
    };
    However, our customer complains that using 100 integers is SOMETIMES not enough, so we need to change it. We then decide to re-construct the class to dynamically allocat the space for array.
    Code:
    class X
    {
       int *pArray;
    public:
       int getX(int index) { return pArray[index]; }
    ...
    };
    Now all our customers MUST recompile all code that uses class X, because the class member information is COMPLETELY different.

    With a called function for getX, the old code would work just fine with the new class, because it needs to know nothing of the array that changed to pArray. [1]

    Where I work, we have to deal with "customers are using this class via a library, and they do not want to recompile all of their code and all of their customers code to make it work again if we change a class". Inline functions are ALLOWED, but you need to be darn sure that you don't want to change them very often (like no more than once in a few years).

    [1] Ok, so changing the size of the array is not a great idea to maintain compatibility, so this would probably break ANYWAYS - but I can't be bothered to re-arrange my example to something that doesn't change size.

    --
    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. #40
    Kung Fu Kitty Angus's Avatar
    Join Date
    Oct 2008
    Location
    Montreal, Canada
    Posts
    115
    Quote Originally Posted by citizen View Post
    Is that your way of saying you'll ignore me? That wasn't a good response to the question I asked you. Are you sure those things are bottlenecks?
    I haven't got a case in mind that is germane to your question. I started this thread for hypothetical reasons, not because I have a specific problem w/a specific piece of code. Yes, there are many ways to optimize, but those are topics for other threads. I started this one because I have written a great many classes in my years programming C++, and I'm wondering if a number of the *tors explicitly defined in them are dead weight or not.

  11. #41
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Angus View Post
    I haven't got a case in mind that is germane to your question. I started this thread for hypothetical reasons, not because I have a specific problem w/a specific piece of code. Yes, there are many ways to optimize, but those are topics for other threads. I started this one because I have written a great many classes in my years programming C++, and I'm wondering if a number of the *tors explicitly defined in them are dead weight or not.
    And we have pretty much uniformly said "probably unless you have checked your performance with and without or otherwise figured out that they have a noticeable performance impact", and you still seem to reply "but I know better". Is that because you didn't like the answers given, or some other reason?

    --
    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. #42
    Kung Fu Kitty Angus's Avatar
    Join Date
    Oct 2008
    Location
    Montreal, Canada
    Posts
    115
    Quote Originally Posted by matsp View Post
    Yes, but several times in this post we have commented on "it is not, generally, a good idea to inline without good reason". Yes, there are cases (getters, setters with simple functions and simple data types) where inlining it is a natural.

    However, not only is inlining sometimes detrimental to performance. It has a completely different-side effect too.

    Let's say we have a scenario where we use a .DLL to implement a class. In version one, we implement the class like this:
    Yes, there is a great multitude of reasons for not inlining. Some are very theoretical and abstract, like the ones I mentioned in the OP, while others are very practical and detailed, such as your DLL example, code readability, portability, build time, etc. The list could go on forever. So there is a lot to consider when deciding to inline. However, the simpler the implementation, the fewer issues there are to consider. And, the greater the number of times this hidden code will be called, the greater the pressure is to inline.
    Sometimes the number of different calls made to a class is so limited, while the number of identical calls to a class is so frequent that benefit of inlining becomes immediately apparent.

  13. #43
    Kung Fu Kitty Angus's Avatar
    Join Date
    Oct 2008
    Location
    Montreal, Canada
    Posts
    115
    Quote Originally Posted by matsp View Post
    And we have pretty much uniformly said "probably unless you have checked your performance with and without or otherwise figured out that they have a noticeable performance impact", and you still seem to reply "but I know better". Is that because you didn't like the answers given, or some other reason?
    I don't know about knowing better, but I think I know enough about the cases I specified. If there are things I wasn't aware of wrt the circumstances of the cases I specified, well that's one thing. But if one introduces new circumstances to a hypothetical case, then what you have is another case.

  14. #44
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I'm wondering if a number of the *tors explicitly defined in them are dead weight or not.
    Any *tor that is explicitly defined is dead weight if that definition doesn't do anything the compiler wouldn't do. But that has nothing to do with whether the thing is inlined or not.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. Inline functions and inheritance
    By hpy_gilmore8 in forum C++ Programming
    Replies: 3
    Last Post: 01-14-2004, 06:46 PM
  3. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  4. bit shifting
    By Nor in forum C++ Programming
    Replies: 9
    Last Post: 08-08-2003, 11:55 AM
  5. Replies: 5
    Last Post: 09-17-2001, 06:18 AM

Tags for this Thread