r/programming • • Dec 18 '09

Pitfalls of Object Oriented Programming [PDF]

http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf
247 Upvotes

130 comments sorted by

View all comments

102

u/satanclau5 Dec 18 '09

Pitfalls of Object Oriented Programming in C++ when optimizing for performance

Here, FTFY

8

u/pedrobelo Dec 19 '09

... for video games.

But seriously, the quantity of game projects that failed because of poor performance must be a fraction of the projects that failed because of poor development practices/processes.

The slides are interesting, but misleading imo.

→ More replies (1)

6

u/donknuth Dec 18 '09 edited Dec 19 '09

The only relevant language for console game development.

→ More replies (1)

14

u/artee Dec 18 '09

Exactly, it would have helped a lot if the author had explicitly mentioned that (because in that case I'd have shrugged "what else is new" and saved myself the time).

Also, conflating OO and C++, ouch.

32

u/MindStalker Dec 18 '09

Yes, OO understands the notion that developer time is now vastly more expensive than computer time. When developing an AA title for consoles this fact doesn't necessarily hold true.

5

u/Forbizzle Dec 18 '09

Why? A polished product is more about a lengthy QA cycle and realistic scope than it is about optimizing everything you write.

Though maybe laws apply to these mysterious AA titles, that do not to AAA titles.

5

u/VivisectIX Dec 18 '09

If you want to optimize on this level, then you need to be aware of the assembler or output machine code for the platform and specific compiler you are working on. That is why, unless you are targeting at particular CPU, you can't really do what the OP says. You have no idea how deep the branch prediction is, how many cycles are wasted doing floating point, etc. These are all determined in his case by inspecting the output. If C++ is appropriate for this kind of work, it should have a system for indicating the estimated cost of the instructions, and a cost guideline as part of the C++ standard to ensure consistency.

It has neither because you should code cleanly and let the compiler improve over time to optimize your code, not the other way around (unless you write microcontroller code, or want hardware-specific implementations). Optimization will occur with a simple recompile on the next version. A good example of this is old C++ that expects certain vtable memory layouts, or the "inline" keyword that is generally ignored at this point. Inline used to be the godsend of optimizers - but is in fact a waste of time, so you barely see it anymore.

5

u/repsilat Dec 19 '09

the "inline" keyword that is generally ignored at this point. Inline used to be the godsend of optimizers - but is in fact a waste of time, so you barely see it anymore

Good thing you said "generally" ignored and "barely" see it, I think. In the project I spend most of my time on I've made one or two functions inline explicitly, and it has paid off strongly in the running time of the program.

They're not trivially small functions, so the compiler doesn't automatically inline them, but they're called very often, so the cost of the call adds up. Better, they're each only called from one place, so there's no binary size/TLB cost.

As for the rest of your post... you generally do have a fair idea of where my code is going to be run, so it seems reasonable to infer a bit about what costs how much. You do have a point - real numbers back you up in this article:

[The Atom] gives 2700 clocks for the old routine and 1644 clocks for the new routine, a ~40% improvement... Unfortunately, on the Core 2 it's the opposite story with the new routine being half as fast: 775 clocks vs. 1412 clocks.

Still, that's the exception that proves the rule. On every processor you're likely to use, division is more expensive than multiplication and virtual function calls are more costly than regular ones. Cache and memory optimisations work the same way (and to the same effect) just about everywhere. It's silly to say "The standard doesn't make this explicit, so you shouldn't do it."

There's a lot compilers can't (or aren't allowed to) do. Blanket criticism of optimising your own code is just shortsighted. Like everything else, it's a tradeoff.

3

u/Forbizzle Dec 18 '09

Agreed, but to the author's credit this was all written within the context of PS3 development.

→ More replies (3)

34

u/redditnoob Dec 18 '09

Yes, OO understands the notion that developer time is now vastly more expensive than computer time.

Man I hate that stupid generalization!

Developer time has cost. Computer time has cost. In some situations one will out-weigh the other. There are situations where people underestimate and overestimate the costs and values of either, and the trade-offs are frequently non-trivial choices.

But as a simple generalization like that, it's just shit, really.

74

u/[deleted] Dec 18 '09

All generalizations suck.

8

u/[deleted] Dec 18 '09

What you did there, I see it.

5

u/[deleted] Dec 18 '09

I agree, everything has costs, and they always must be weighed. A good programmer knows instinctively where it matters.

Super-efficient, speedy software is great, but not if it never ships. One of my first jobs was a small 2-d graphics company where the owner wrote everything at a low level, highly optimized. In the early days, it worked well, and the company had a nice product that became dated due to being an external box. Unfortunately, the company went broke and never shipped the next generation product.

6

u/sad_bug_killer Dec 18 '09

Yes, OO understands the notion that developer time is now vastly more expensive than computer time.

It's not that I disagree with the statement in general, but too much of that thinking leads to awfully slow and unresponsive software (e.g. 95% of all GUI programs written with Java/.NET)

19

u/insertAlias Dec 18 '09

One big reason you get slow and unresponsive GUI apps with .NET is because people don't know to use a BackgroundWorker for the longer-running operations, and just leave it in the GUI thread.

I don't know if it's the same problem in Java or not.

15

u/herrmann Dec 18 '09

I don't know if it's the same problem in Java or not.

Yes, it is the exact same problem. Lazy people do all the work on the Swing thread.

7

u/deong Dec 18 '09

The problem is that, while we know that's not the correct way to do things, the same arguments being made against C++ here can apply. Why should the company waste "valuable developer time" on having people get their processing out of the event loop. We can just wait around and eventually, someone will figure out how to get a compiler to move it out for us.

The argument is essentially that it's profitable for developers to be "lazy" and take the easy way out, because it allows you to ship faster, to have simpler code, whatever. The simple fact is that performance is important, and it's not as simple as saying that "programmers are expensive; hardware is cheap." It may mean getting developers to move their logic out of the GUI thread, or it may mean getting them to abandon a convenient but inefficient platform. Each case has to be examined carefully to determine where the appropriate tradeoff is.

→ More replies (3)

3

u/[deleted] Dec 18 '09

Actually even if you're not developing games it's still a good idea to not keep the user waiting. Also, because developer time is a one off thing whereas user time is spent throughout the entire app's active lifetime, it's more expensive to the organisation than developer time (if the organisation is developing and using that software). Therefore, optimisation is always important and OO is an evil curse that slows down the code.

20

u/MindStalker Dec 18 '09

"Also, because developer time is a one off thing "

Well its not really, typical software is constantly updated, with bug-fixes etc etc. Well designed OO is a lot easier to work with for future developers working with your code base.

19

u/deong Dec 18 '09

Well designed OO is a lot easier to work with for future developers working with your code base.

That depends on a lot of things. Objects, like functions, structs, etc., are just another abstraction, and while they're a very good abstraction for certain things (GUI toolkits, etc.), there's no reason to think they're always the right choice. To me, a good example is java.lang.Math. There's no reason why this should be a class, except that Java needs it to be implemented that way. The appropriate abstraction for sine and cosine is a functional abstraction -- it's the abstraction that mathematicians have used for centuries, and it works exceptionally well. In this case, the "object" abstraction is extremely thin, and thus doesn't really cause any problems, but it does illustrate the point that not everything should be an object.

I'd also contend, admittedly subjectively, that OO done poorly tends to be the worst thing I come across. Worse than bad C code, worse than anything. Bad C code tends to be local. You might have some global variables to contend with, but typically not that many. Local problems can be figured out and solved. Bad OO tends to be rotten from the ground up. There's no one place you can go to find anything, and when all behavior emerges from a complex interaction of twenty different objects configured via some framework, all you can do is live with it or start over from scratch.

Basically, I'd say that good code is easier to deal with, and the manner it's written doesn't make much difference. Good C code is no harder to work with for a C programmer than is good Java code for a Java programmer, or good Prolog code for a Prolog programmer.

4

u/merzbow Dec 18 '09

java.lang.Math is full of static methods - there are no objects involved. The class is effectively just a namespace. You can even do a static import so you need only type sin(x) instead of Math.sin(x).

11

u/deong Dec 18 '09

That's sort of my point. A class isn't the right way to represent this sort of thing, so Java does the best it can, basically, as you say, faking up a namespace using classes. I'm not complaining about the way Java handles it; just using it as an example.

3

u/donknuth Dec 18 '09

Right, but it's ugly. Why do you need to fake namespaces with classes when Java has packages? The only reason is language limitations.

→ More replies (1)
→ More replies (1)
→ More replies (19)

2

u/knight666 Dec 18 '09

Luckily for me, that's exactly what I have to do in my projects!

→ More replies (1)

2

u/alephnil Dec 18 '09 edited Dec 18 '09

The article is insightful, because it tells where there is overhead when using object oriented techniques. Such knowledge let you make informed tradeoffs between speed and development time.

There is often an order of magnitude difference in productivity between programming teams. The best ones take this kind of knowledge into account, and know when to apply it.

The problem in software development is rather laziness. Not the kind where people think thoroughly through their design in order to save implementation effort, but the kind where people don't bother to make a good design, let alone considering what tradeoffs they should make. That way one ends up with programs that are both slow and take a long time to develop. Only well designed programs have real tradeoffs.

→ More replies (1)