-1

I was reading some C++ object-oriented programming notes that mentioned that we should avoid wrapping functions in classes if it is not required, since wrapping 'things' in classes would reduce efficiency.

Is it true that wrapping functions in classes reduces efficiency? What other 'things' could reduce efficiency when wrapped in classes?

7
  • 5
    The only person that can tell you what a specific person meant when they wrote a specific thing is the specific person who wrote that specific thing. We are not mind-readers, so it is generally more or less impossible to answer the question "what did person X mean when they said Y". Case in point: how do you define "things"? How do you define "wrapping in classes"? What do you mean by "reduce efficiency"? What efficiency are you talking about? The efficiency of reading the code? The efficiency of writing the code? The efficiency of testing the code? The efficiency of maintaining the code? Commented Mar 7, 2021 at 11:57
  • @JörgWMittag I am not asking what the author meant; I am asking if this is true, in general, in software engineering (regardless of the author's person's opinion). Notice that I asked "Is this true?", not "Is the author correct?". Commented Mar 7, 2021 at 11:59
  • What programming language are you talking about? The vast majority of object-oriented languages I am using on a regular basis don't even have functions. Some of the object-oriented languages I am using don't have classes. Commented Mar 7, 2021 at 11:59
  • 5
    In that case, you really need to supply a precise, unambiguous, objective definition of what, exactly you mean by "things", "wrapping things in classes", "efficiency", and "reducing efficiency", and what specific programming language you are talking about. Commented Mar 7, 2021 at 12:01
  • 1
    About the "things" thing: generally speaking, some of the other "things" you could wrap are other classes/objects, classes coming from a library you're using, a collection of functions that call some API, or primitive types (like int, float, etc.). You might do this to integrate different parts of the system, or 3rd party code, or to make use of polymorphism. Commented Mar 7, 2021 at 18:54

3 Answers 3

10

This statement is either wrong or incomplete:

  • Calling a non-virtual member function requires exactly the same code as calling a free function with one additional pointer argument. That's peanuts.

    For a fair comparison: writing a free function equivalent to the member function would require exactly this additional argument to access to the object's state (or pass the pointer to another function that would need to access the object state): in this case, the same code is generated so that there is no real overhead.

  • If the object state is not at all relevant, you could spare this extra paramater. But you could then as well make the function a static member function, which leads to exactly the same assembly code as a free function.

  • Calling a virtual member function requires an additional overhead: for each call, the right function to call must first be found. This is usually done with a virtual table. It's a couple of extra nanoseconds (some more nanoseconds in case of multiple inheritance combined with virtual inheritance, but this is quire rare in practice since it can be avoided with composition over inheritance). In most cases (i.e. if you're not working on a rendered in major game), there is no need to worry about real performance issues.

    For a fair comparison, if you need polymorphic behavior and would write the same functionality with a free function, you'd have to add a couple of extra if-else or switch-case-default to achieve the same result, and these would also cost a couple of nanoseconds more at each call and perhap's several times. So the cost-benefit in terms of performance is not necessarily in favor of the free function. (not to speak of the more difficult maintenance)

Conclusion: write your code with a proper design. Use member function when needed. Make the function virtual if polymorphism is required. At a later stage, if you really encounter performance issues, use a profiler to see where tthe real bottleneck is.

Quote of the day:

Don't diddle code to make it faster — find a better algorithm.

3
  • Thanks for the answer. For the record, what I wrote is the 'complete' statement that was provided to me. Commented Mar 7, 2021 at 12:57
  • 3
    @ThePointer - what Christophe meant by "incomplete" was that the original statement, as made by the author, was perhaps too handwavy (incomplete = it didn't go into enough detail to avoid being misleading). Any higher level mechanism will likely incur some small performance penalty, but we make these tradeoffs all the time, and most of the time it doesn't matter at all (computers are fast) - so you don't have to default to an unusual and obscure way of writing code just to avoid some presumed performance issue. Improving performance in non-bottleneck parts of the program ... 1/2 Commented Mar 7, 2021 at 18:49
  • 2
    @ThePointer ...does nothing to help the performance, but it will very likely hurt the ability of you and others to understand, maintain and debug that code. To quote Knuth: "The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming." Generally, when it comes to performance, you want to focus on the critical parts; you pinpoint the bottleneck(s) by measuring (using tools designed for that). 2/2 Commented Mar 7, 2021 at 18:49
3

Do you have an application where you need to squeeze out the last bit of performance from the user’s computer? Chances are that you don’t. For 99.9% of your code the nanoseconds that you might waste by wrapping things in a class don’t matter.

And when it matters, you will likely find that optimisation is a lot easier if something is wrapped in a class and you have just one place to optimise.

What you really should think about: Development time. If you want speed, then writing code that is easier to maintain and develop saves you time, which you can use to find places where you can save milliseconds instead of nanoseconds.

1
  • 3
    Actually, it's not only development time: long chains of if-else required to simulate polymorphic code in non-polymorphic functions, adds extra overhead (and the condition evaluations are sequential, so that in worse case, it might be much less performant than going through a virtual table to the right code directly) ;-)
    – Christophe
    Commented Mar 7, 2021 at 13:13
0

"At so-many billion operations per second," these days, *it probably just doesn't matter anymore."

We've gotten really good at "throwing silicon at it," maybe because these days we've got so much silicon to throw.

What does still matter, however, is clarity, and maintainability. Please focus only upon these things, not [theoretical worries about ...] "efficiency."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.