Jump to content
  • Advertisement
Sign in to follow this  
Shyr

OOP and DOD

This topic is 958 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Recently, I have been studying various design patterns. While they all seem very interesting and useful in different situations, I think I've gotten a little confused about structuring my code. Code is never clean enough. So I spend much time refactoring and thinking of better ways to simplify code to make it easier to read later.

 

I would like to hear about your opinions of Object-Oriented Programming and Data-Oriented Design. I'm not really asking if I should not be using one or the other, but rather when and how I should efficiently use OOP and DOD?

 

OOP as I mean it here refers to classes with an interface, attributes, and methods.

DOD as I mean it here refers to structures with external functions that use them.

Share this post


Link to post
Share on other sites
Advertisement

OOP and DOD are two very useful paradigms among hundreds, possibly thousands, that developers can pull out as appropriate.

 

Although religious wars have been fought over nuance, object oriented effectively means that you have objects and the objects have a series of functions/methods to perform a cluster of tasks.  

 

Similarly subject to religious wars, data oriented effectively means that you are organizing data in a way that is friendly to the cache or other underlying hardware.

 

As the programmer you can use one, the other, or both, as you see fit in your code. You can also use flow based paradigms, event driven paradigms, parallel paradigms, and more, in whatever ways you see fit in your code.

Share this post


Link to post
Share on other sites

 

 

I would like to hear about your opinions of Object-Oriented Programming and Data-Oriented Design. I'm not really asking if I should not be using one or the other, but rather when and how I should efficiently use OOP and DOD?

 

 

Ok I'm trying to think of a way to answer this without getting into several paragraphs, starting a religious war, or pointlessly confusing you. 

 

The thing to understand is that OOD/DOD are about organizing data within your game/app and how that data is transformed from one state to another.  At the end of the day both will get you where you're going, to get your game level from one frame to the next one.  I'd say that if you're trying to figure out when to use OOD versus DOD, I'd consider these 3 main things:

 

1) Is your problem mainly about optimization, about running a simulation as fast as possible?  If so, DOD might be the best way for you to go.

 

2) Do you have smaller numbers of objects that interact in complex ways with each other during an update?  OOP is probably better for you.  But,

Do you have large numbers of objects that dont interact with each other?  DOD is probably better and faster.

 

and

 

3) Is multi-threading a consideration?  In this case DOD might be better for you.

Share this post


Link to post
Share on other sites
In my opinion, and I'm assuming we're talking about high performance software development and C++ (since you've tagged the thread with this language), use DOD whenever possible and OOP when forced to because (even though I'm not sure if DOD has been formally and completely defined) what comes to mind technically when thinking of it is that it help us to tackle a couple of problems with OOP:

1. Inheritance abuse (including CPU costs of virtual function calls although generally that is an optimization).

2. Cache wastage through composition abuse and inheritance.

3. Destructors, constructors, member functions, member operator overloading, etc. leading more functional code writing instead of OOP.

Technically, as been stated before, the main result that you get from this is more POD and less objects, sometimes automagically achieving a better memory usage. Ultimately, you want to balance these things so that your only reason to use the (few) advantages of OOP is convenience.

Share this post


Link to post
Share on other sites
 

In my opinion, and I'm assuming we're talking about high performance software development and C++ (since you've tagged the thread with this language), use DOD whenever possible ...

 

Let me expand a bit on this -- DOD is really the art of wringing utmost performance from a set of hardware that has specific, real-world characteristics -- machines have a word-size, a cache-line size, multiple levels of cache all with different characteristics and sizes, it has main memory, disk drives, and network interfaces all of which have specific bandwidths and latencies measurable in real, wall-clock time. Furthermore it has an MMU, and DMA engines, and it has peripheral devices that require or prefer that memory objects used to communicate with it appear in a certain format (e.g. compressed textures, encoded audio). Because of the already large -- and still growing -- disparity between memory access speed and CPU instruction throughput, it has been a lesser-known truth for some time that memory-access patterns, not CPU throughput or algorithmic complexity, is the first-order consideration for writing performant programs. No fast CPU or clever algorithm can make up for poor memory access patterns on today's machines (this was not the case earlier in computing history when the disparity between memory access speeds and CPU throughput was not so mismatched; I would estimate it has been the case since around the time of the original Pentium CPU, but hadn't become visible to more mainstream programmers until probably 10 years ago, or less).

 

If performance is critical, DOD is the only reasonable starting point today. Period. End of Story.

 

But one must have a reasonable grasp of where performance is critical -- it would be unwise to program every part of your program at every level as if DOD is necessary or desirable in the same way that writing the entirety of your program in Assembly language would be -- in theory, you might end up with the most efficient program possible, but in practice you'll have put an order of magnitude more effort into a lot of code that never needed that level of attention to do an adequate job, and you'll have obfuscated solutions to problems where other methods lend themselves naturally. For instance, UI components would gain nothing by adopting DOD, yet a DOD solution would likely give up OOP approaches that fit the problem so naturally that UI widgets are one of the canonical example-fodder used when teaching OOP.

 

 

 

... and OOP when forced to because (even though I'm not sure if DOD has been formally and completely defined) what comes to mind technically when thinking of it is that it help us to tackle a couple of problems with OOP:

1. Inheritance abuse (including CPU costs of virtual function calls although generally that is an optimization).

2. Cache wastage through composition abuse and inheritance.

3. Destructors, constructors, member functions, member operator overloading, etc. leading more functional code writing instead of OOP.

Technically, as been stated before, the main result that you get from this is more POD and less objects, sometimes automagically achieving a better memory usage. Ultimately, you want to balance these things so that your only reason to use the (few) advantages of OOP is convenience.

 

Yet, its important to maintain awareness that OOP and DOD are not necessarily at odds. You can't, for example, answer the question "what's DOD?" with "Not OOP." Whatever programming paradigm(s) you choose to adopt, its prudent to select and leverage what features it can offer in service of DOD, for the parts of your program that adopt DOD. It might not be possible to write a DOD solution that looks exactly like a typical OOP solution, but its very possible to write a DOD solution that looks *more like* a typical OOP solution than like a typical Procedural solution. Again, DOD is (and must be) prime where you have deemed performance to be critical, but there are no language features or programming paradigms that it forbids; like all things in engineering, there must always be a considered balance of competing needs.

Share this post


Link to post
Share on other sites

 

But one must have a reasonable grasp of where performance is critical -- it would be unwise to program every part of your program at every level as if DOD is necessary or desirable in the same way that writing the entirety of your program in Assembly language would be -- in theory, you might end up with the most efficient program possible, but in practice you'll have put an order of magnitude more effort into a lot of code that never needed that level of attention to do an adequate job, and you'll have obfuscated solutions to problems where other methods lend themselves naturally. For instance, UI components would gain nothing by adopting DOD, yet a DOD solution would likely give up OOP approaches that fit the problem so naturally that UI widgets are one of the canonical example-fodder used when teaching OOP.

 

QFT. One of the reasons that DOD is still relatively unknown outside of certain areas (game programming, high-performance computing) is because it solves a very specific problem: memory access bound performance.

 

But for the vast majority (IMHO) of software written today, CPU/memory bound performance is an order of magnitude less important than the much lower bandwidth issues (data access, network access, etc).

 

Most "typical" business software spends its time waiting for database queries or REST APIs to complete. If DOD improves your algorithm even by 1000%, that's not going to help much if the total time spent waiting for process x to complete is 90% dependent on a high latency process.  

 

I'm not arguing against DOD; it's very good for it's intended purpose. I'm simply attempting to explain why it's not more widely known.

Share this post


Link to post
Share on other sites

Thanks so much everyone. From what I gathered it seems that DOD, or functional programming, is faster than OOP but OOP is better for more complex behaviors. I often hear that using inheritance, abstract classes, polymorphism and such is slower due to v-table searches, but does that cause significant reduction of performance (to the point where say a player would notice)?

 

I like the idea of using abstract data and objects in C++ because it seems like a good way to organize code. On the other hand, I don't want to make a code base that is terribly inefficient.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!