Many computational scientists that I know of, including myself for example, are not computer scientists. As such they are often not very well aware more advanced techniques in OOP. On the other hand, most of advanced programmers are not computational scientists. They may not be well aware of what OOP features are essential or relevant when it comes to write a scientific computing software.

Considering mainly C++ (but maybe also in general), what OOP features do you think are absolutely necessary in a number crunching software and why? What features do you think are generally considered good, but might cause unnecessary overhead? What are some of the "myths" when it comes to overhead of using more advanced features?

I generally like to hear things regarding:

1 - templates

2 - virtual functions

3 - smart pointers and garbage collectors

[EDIT:] 4 - operator overloading

5 - Boost library (technically not an OOP feature but very popular C++ library)

closed as not a real question by Aron Ahmadia Mar 23 '12 at 15:58

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    GradGuy, welcome to scicomp! This is an important question, but I think it is poorly phrased for two reasons. The first is that it is a list-style question, and these are strongly disregarded on Stack Exchange sites, particularly because they tend to elicit opinions instead of solid facts. The second is that "object-oriented programming" refers to a very specific set of programming techniques, and what you are referring to in your question is mostly "features of modern programming languages". I don't think this question can be saved, but I will let the community decide. – Aron Ahmadia Mar 23 '12 at 10:04
  • Jack had a very nice comment on this elsewhere. Excerpt : "My approach has been to use C++ for everything but computational kernels, which are usually best written in either assembly or Fortran; this buys you all of the performance of the traditional HPC approach but allows you to simplify the interface, e.g., by overloading computational kernels like SGEMM/DGEMM/CGEMM/ZGEMM into a single routine, say Gemm. Clearly the abstraction level can be raised much higher by avoiding raw pointers and switching to opaque classes, but it is a nice first step." – Inquest Mar 23 '12 at 11:01
  • Maybe you want to rephrase the question to "How useful are modern OOP concepts in scientific computing?" or "What are the benefits of modern OOP concepts in large-scale SC?" "What level of complexity reduction has OOP brought to SC over C or FORTRAN?" – Deathbreath Mar 23 '12 at 11:55
  • Some insight from folks who work on math libs ... lists.mcs.anl.gov/pipermail/petsc-dev/2010-April/002607.html – stali Mar 23 '12 at 12:56
  • I like this question, but it is unfortunately a bit too broad. I really like @Deathbreath's suggestions, and I would further suggest that you ask about one specific programming paradigm at a time (i.e. a question only about the use of expression templates). Welcome to the site, and I'm looking forward to seeing your contributions. – Aron Ahmadia Mar 23 '12 at 15:57
up vote 7 down vote accepted

I'm not a big user of OOP in general, and this has its reasons. My thoughts on some of the features you mention:

  • Templates: Convenient when they work, a massive nightmare to debug when they don't. Furthermore, you don't really know what's going on "behind the scenes", which can be a source of errors or inefficiencies.
  • Virtual functions: Can be very convenient and elegant, but keep in mind that calling that function is more expensive than calling a static function. Don't use these things in the innermost loop of a big calculation.
  • Smart pointers: As with virtual functions, watch out for hidden overheads when assigning and dereferencing. Don't use in performance-critical parts of your code.
  • Garbage collectors: Not necessarily an OOP feature (e.g. the Boehm GC), but an awesome thing nevertheless. Again, this can cause your program to pause and wait while cleaning up the memory, but you should avoid excessive creation/allocation and destruction/freeing of objects in performance-critical parts anyway, right?

One thing you left out is operator overloading, which is an extremely convenient way of expressing things in a readable manner. Again, though, watch out for overheads in tight loops, and remember that in general, the compiler will not be able to optimize anything (think common sub-expression elimination, register variables, etc.). A good alternative are expression templates, but writing your own can increase code complexity and give you weird bugs, think the same kind of mess as regular templates can be.

Having said that, using other people's templates, assuming they are tried and tested and mostly bug-free, can make life so much sweeter. Remember though: can, as in not always.

In summary, it's a performance/elegance trade-off. I would definitely recommend OOP, or anything similar, for the user interfaces and/or "big picture" parts of the code. I would, however, stay away from it in kernels or anything performance-critical due to the hidden overheads and the fact that the compiler usually can't optimize much.

I think that the most important lesson for scientists that start programming is "There is a very high probability that the programming problem that you are struggling with has already been solved by a computer scientist".

I want to refer here to "Design Patterns": a lot of typical interactions between objects, their behaviour and such, is well captured in a limited number of patterns that have a reference implementation in many OO programming languages like C++, Java, Python, ...

The reference for design patterns is Design Patterns by "The Gang-of-Four" (commonly referred to as the GoF). It's complete, but not easy to read in the evening with a glass of wine. A more tutorial approach is Head First Design Patterns, which I can recommend.

So when starting a programming job, first do the OOP analysis (identify objects, behaviours, relations), then identify patterns and implement these using their reference implementation.

"Excessive" use of templates in C++ can lead to humongous compilation errors and might lead to frustration with non-computer scientists. In form of expression templates it can significantly speed up your code though, and that's something you should be aware of.

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