> I am surprised to see that so many programmers still like to reason and guess what the performance of their program is instead of profiling it...
Yeah, us old fuddy-duddies. We also like to reason about the correctness of our code while we're constructing it, instead of writing all of it and testing it. Crazy, huh? Like deep correctness, a performant system does not come from sprinkling some tools over at the end; it's an emergent property of attention to detail at every step.
The performance problems a profiler can show you are the easy ones. Hard performance problems come from users, where you can't touch, feel, and measure the code's dynamic behavior. Somewhere out there, in some customers' hands, software you barely remember writing three years ago is crawling along, and the customer is too livid to clearly express what she's doing to make it slow.
Just like debugging a tough correctness bug from the field, you are stuck alternating between deduction and induction. You try to piece together what the user did, and with luck you can reconstruct the bug! Yay, profile it, deduction worked! But I was almost never this lucky. I was left stuck using my bottom-up understanding of what the source code does and how it could have interacted with the user's setup. Identify a possible critical path for this workload, and stare at that motha with a critical eye: "I think you're slow sometimes. But obviously not always. Why? What could make you slow?"
C++ makes this part much, much harder, because even having narrowed it down to a candidate critical path, you can't look at the source code to know (as reliably and quickly as with C) what the hardware is going to do. Notice the qualifiers there (as reliably, as quickly). I'm sure a C++ expert like yourself could rattle off the whole flying circus of default constructors, copy constructors, operator overloads, and destructors that the compiler spits out, but to do so you will need non-local information in a way that you do not for C.
If these problems don't arise in your practice, awesome, good for you. Your marginal user doesn't consider performance problems bugs. That's a great situation to be in, because it lets you focus on features. But it does lead to question of why you are using C++.
> I don't want to match malloc/free calls, strcat strings together or realloc pointers.
If you don't occasionally really need realloc, that's cool, nothing wrong with that, but what kind of resource-intensive software are we talking about, then? It's an important tool in the toolbox when trying to implement data structures that occupy significant fractions of your address space.
Yeah, us old fuddy-duddies. We also like to reason about the correctness of our code while we're constructing it, instead of writing all of it and testing it. Crazy, huh? Like deep correctness, a performant system does not come from sprinkling some tools over at the end; it's an emergent property of attention to detail at every step.
The performance problems a profiler can show you are the easy ones. Hard performance problems come from users, where you can't touch, feel, and measure the code's dynamic behavior. Somewhere out there, in some customers' hands, software you barely remember writing three years ago is crawling along, and the customer is too livid to clearly express what she's doing to make it slow.
Just like debugging a tough correctness bug from the field, you are stuck alternating between deduction and induction. You try to piece together what the user did, and with luck you can reconstruct the bug! Yay, profile it, deduction worked! But I was almost never this lucky. I was left stuck using my bottom-up understanding of what the source code does and how it could have interacted with the user's setup. Identify a possible critical path for this workload, and stare at that motha with a critical eye: "I think you're slow sometimes. But obviously not always. Why? What could make you slow?"
C++ makes this part much, much harder, because even having narrowed it down to a candidate critical path, you can't look at the source code to know (as reliably and quickly as with C) what the hardware is going to do. Notice the qualifiers there (as reliably, as quickly). I'm sure a C++ expert like yourself could rattle off the whole flying circus of default constructors, copy constructors, operator overloads, and destructors that the compiler spits out, but to do so you will need non-local information in a way that you do not for C.
If these problems don't arise in your practice, awesome, good for you. Your marginal user doesn't consider performance problems bugs. That's a great situation to be in, because it lets you focus on features. But it does lead to question of why you are using C++.
> I don't want to match malloc/free calls, strcat strings together or realloc pointers.
If you don't occasionally really need realloc, that's cool, nothing wrong with that, but what kind of resource-intensive software are we talking about, then? It's an important tool in the toolbox when trying to implement data structures that occupy significant fractions of your address space.