Skip to content Skip to sidebar Skip to footer

Encapsulation Severely Hurts Performance?

I know this question is kind of stupid, maybe it's a just a part of writing code but it seems defining simple functions can really hurt performance severely... I've tried this simp

Solution 1:

Function call overheads are not big; you won't normally notice them. You only see them in this case because your actual code (x*x) is itself so completely trivial. In any real program that does real work, the amount of time spent in function-calling overhead will be negligably small.

(Not that I'd really recommend using foo, identity and square in the example, in any case; they're so trivial it's just as readable to have them inline and they don't really encapsulate or abstract anything.)

if they're not supposed to be changed then why not just replace every instance of 'magic' with a literal before the code compiles?

Because programs are written for to be easy for you to read and maintain. You could replace constants with their literal values, but it'd make the program harder to work with, for a benefit that is so tiny you'll probably never even be able to measure it: the height of premature optimisation.

Solution 2:

Encapsulation is about one thing and one thing only: Readability. If you're really so worried about performance that you're willing to start stripping out encapsulated logic, you may as well just start coding in assembly.

Encapsulation also assists in debugging and feature adding. Consider the following: lets say you have a simple game and need to add code that depletes the players health under some circumstances. Easy, yes?

def DamagePlayer(dmg):
    player.health -= dmg;

This IS very trivial code, so it's very tempting to simply scatter "player.health -=" everywhere. But what if later you want to add a powerup that halves damage done to the player while active? If the logic is still encapsulated, it's easy:

def DamagePlayer(dmg):
    if player.hasCoolPowerUp:
        player.health -= dmg / 2else
        player.health -= dmg

Now, consider if you had neglected to encapulate that bit of logic because of it's simplicity. Now you're looking at coding the same logic into 50 different places, at least one of which you are almost certain to forget, which leads to weird bugs like: "When player has powerup all damage is halved except when hit by AlienSheep enemies..."

Do you want to have problems with Alien Sheep? I don't think so. :)

In all seriousness, the point I'm trying to make is that encapsulation is a very good thing in the right circumstances. Of course, it's also easy to over-encapsulate, which can be just as problematic. Also, there are situations where the speed really truly does matter (though they are rare), and that extra few clock cycles is worth it. About the only way to find the right balance is practice. Don't shun encapsulation because it's slower, though. The benefits usually far outweigh the costs.

Solution 3:

I don't know how good python compilers are, but the answer to this question for many languages is that the compiler will optimize calls to small procedures / functions / methods by inlining them. In fact, in some language implementations you generally get better performance by NOT trying to "micro-optimize" the code yourself.

Solution 4:

What you are talking about is the effect of inlining functions for gaining efficiency.

It is certainly true in your Python example, that encapsulation hurts performance. But there are some counter example to it:

  1. In Java, defining getter&setter instead of defining public member variables does not result in performance degradation as the JIT inline the getters&setters.

  2. sometimes calling a function repetedly may be better than performing inlining as the code executed may then fit in the cache. Inlining may cause code explosion...

Solution 5:

Figuring out what to make into a function and what to just include inline is something of an art. Many factors (performance, readability, maintainability) feed into the equation.

I actually find your example kind of silly in many ways - a function that just returns it's argument? Unless it's an overload that's changing the rules, it's stupid. A function to square things? Again, why bother. Your function 'foo' should probably return a string, so that it can be used directly:

''.join(foo(x)," -- bar !! "])

That's probably a more correct level of encapsulation in this example.

As I say, it really depends on the circumstances. Unfortunately, this is the sort of thing that doesn't lend itself well to examples.

Post a Comment for "Encapsulation Severely Hurts Performance?"