What determines performance?
The fundamentals: data structures, algorithms, computer architecture, hardware. Plus overhead.
An OOP program can be designed to align exactly with the choice of data structures and algorithms that is deemed optimal by CS theory. It will have the same performance characteristic as the optimal program, plus some overhead. The overhead can usually be minimized.
However, a program that is initially designed with only OOP concerns, without concerning the fundamentals, may be initially sub-optimal. The sub-optimality is sometimes removable by refactoring; sometimes it is not - requiring a complete rewrite.
Caveat: does performance matter in business software?
Yes, but time-to-market (TTM) is more important, by orders of magnitude. Business software place the emphasis on the adaptability of the code to complex business rules. Performance measurements should be taken throughout the development life cycle. (See section: what does optimal performance mean?) Only marketable enhancements should be made, and should be gradually introduced in later versions.
What does optimal performance mean?
In general, the issue with software performance is that: in order to prove that "a faster version exists", that faster version must come into existence first (i.e. no proof other than itself).
Sometimes that faster version is first seen in a different language or paradigm. This should be taken as a hint to improvement, not a judgment of inferiority of some other languages or paradigms.
Why are we doing OOP if it may hinder our search for optimal performance?
OOP introduces overhead (in space and execution), in return for improving the "workability" and hence the business value of the code. This reduces the cost of further development and optimization. See @MikeNakis.
Which parts of OOP may encourage an initially sub-optimal design?
The parts of OOP that (i) encourages simplicity / intuitiveness, (ii) use of colloquial design methods instead of fundamentals, (iii) discourages multiple tailored implementations of same purpose.
- Object design (e.g. with CRC cards) without giving equal thoughts to fundamentals)
Strict application of some OOP guidelines (encapsulation, message passing, do one thing well) will indeed result in slower code at first. Performance measurements will help diagnose those issues. As long as the data structure and algorithm aligns with the theory-predicted optimal design, overhead can usually be minimized.
What are the common mitigations to OOP overheads?
(welcome to edit)
How could we adopt OOP without sacrificing performance?
Learn and apply both the OOP and the fundamentals.
It is true that strict adherence to OOP may prevent you from writing a faster version. Sometimes a faster version can only be written from scratch. This is why it helps to write multiple versions of code using different algorithms and paradigms (OOP, generic, functional, mathematical, spaghetti), and then use optimization tools to make each version approach the observed maximal performance.
Are there types of code that will not benefit from OOP?
(Expanded from the discussion between [@quant_dev], [@SK-logic] and [@MikeNakis])
- Numerical recipes, which originate from mathematics.
- The mathematical equations and transforms themselves can be understood as objects.
- Very sophisticated code transformation techniques are needed to generate efficient executable code. The naive ("white-board") implementation will have abysmal performance.
- However, today's mainstream compilers are unable to do so.
- Specialized software (MATLAB and Mathematica, etc) have both JIT and symbolic solvers able to generate efficient code for some sub-problems. These specialized solvers can be seen as special-purpose compilers (mediators between human-readable code and machine-executable code) which will themselves benefit from an OOP design.
- Each sub-problem requires its own "compiler" and "code transformations". Therefore, this is a very active open research area with new results appearing every year.
- Because research takes long time, software writers have to carry out optimization on paper and transcribe the optimized code into software. The transcribed code might indeed be unintelligible.
- Very low level code.