可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This is an interview question, the interview has been done.
What things can make C++ slower than C ?
The interviewer asked it very deep and always asked "anything else ? " whenever I said something.
My ideas:
C++ features not available in C may have some cost.
For example, if we use assignment to initialize class's members inside a constructor not by the initialization list, the member's default constructor may be called once before the body of the constructor, and then that value wiped out by the assignment.
Virtual functions need to be called by searching virtual function pointer. This is a overhead.
Any better ideas ?
Any help will be appreciated.
thanks !!!
回答1:
Nothing. In fact, C++ is faster than C. Ever compared std::sort
to qsort
?
People say that virtual functions cost time to call. They do. But so does the C equivalent of looking up in a vtable. If you write equivalent logic in both languages, the C++ version will be more maintainable, cleaner, and faster.
Edit: Oh yeah, you can call printf
from C++ if you want, or completely re-do the stream implementation if you want.
And did I mention that the performance of a program which crashes due to a misplaced NULL terminator is fairly immaterial?
Macros and inline functions will "bloat" a C executable just as surely as templates will in C++.
回答2:
There's nothing inherently slower about C++ versus C, but still, idiomatic C++ code tends to be a lot slower and heavier than idiomatic C code doing the same task. The word idiomatic is key here; if you write your C code to perform a task exactly the same way you would perform that task in C++, it's going to be just as slow. On the other hand, if you're aware of where the hidden costs typically creep up in C++, you can make an effort to keep them minimal and get the benefits of C++ without as many of the costs.
First and foremost is dynamic memory allocation. In C, you see every bit of dynamic memory allocation you do, because it's all explicit (either in the form of calls to malloc
or calls to third-party library functions which return allocated objects). In C++, many class objects where the object's storage duration is automatic will still incur dynamic memory allocation due to hidden allocations taking place in their constructors. A good C++ STL (or third-party library) implementation can avoid a lot of this cost by including small buffers inside the objects themselves, and only performing dynamic allocations when a large buffer is needed, but very few do this in practice. (If I'm not mistaken, llvm's libc++ does, but GCC's libstdc++ does not.) Since this is a quality of implementation issue that's often outside the control of your own code, the main thing you can do here to minimize the impact is be aware of the possibility that automatic objects allocate dynamic memory, and avoid creating more than you need (for example, by using pointers or references when possible). This has other benefits to your code, too.
Another big area is string handling. In idiomatic C, strings are constructed in one fell swoop with snprintf
or similar. In C++ and many other languages with more powerful string classes/types, concatenation (piece by piece construction) of strings is idiomatic. This is very inefficient, leading to multiple allocation/deallocation steps, copies, etc. not to mention the resulting memory fragmentation. I'm not sure what best practices for C++ would involve (I'm not well-versed in C++), but there should be ways to minimize this impact.
And most generally, of course, hidden code. This is sort of a catch-all. It's easy in C++ to write code whereby a lot of extra code you never see gets executed. Constructors/destructors, overloaded operators, and templates are the most obvious causes. Again, if you want to do things the same way in C, the cost will be the same, but the difference is that in C, you see the cost right away because you have to write it yourself.
回答3:
Wow ... a lot of love for C++ in the answers, so I'll rant a bit as Devil's Advocate.
At the atomic language scale, I'd agree that little or nothing is intrinsically significantly "slower" executing in C++. At the higher level, it get's complicated. C++ is a useful tool, but is often a panache bandied about inappropriately as an solution for a all problems. It's better when we use the simplest language to describe a problem, and sometimes that's C++ other times ... assembly, opcodes, interpreted languages.
C++ relies to a larger degree on the compiler to "interpret" intention, crawling through many layers of templates, classes, macros, etc..., with multiple iterations. Each loop through the translation has the potential of encountering the law of unintended consequences . As far as I know, processors don't have registers or opcodes that natively handle the constructs C++ has, so each has to be broken down to a simplified portion. In this area, the compiler and code standards are king. In some cases it's the philosophical equivalent of a teacher with PHD in Mathematics (the compiler) teaching third graders (the processor).
I like C++ and use it conservatively but I've seen little of it written well over the years. I'd like to force some to look at the assembly or machine code ultimately regurgitated by the build, until they understood how convoluted it can be. Bad C is one thing, bad C++ can be exponentially worse.
The better answer for the interview... "When would your team view C++ as not the answer to the problem?"
回答4:
Most features in C++ are a solution to solve a (potential) problem in C (for example: constructors to ensure validity of created data bundles (struct
in C)
This means that to write a correct program in C that tries to avoid a problem for which there is a C++ feature, you will have to perform similar actions that C++ is doing behind the scenes. This results in similar performances in both cases.
Of course you can always write sloppy programs that are "faster", but will not work correctly in all cases
回答5:
C has restrict
, C++ doesn't, although most compilers have it as an extension.
There's also variable length arrays which C++ doesn't have.
回答6:
Any better ideas ? Any help will be appreciated.
The STL as such in C++ is seldom slower than a specially coded equivalent in C. However, the convenience of the STL can occasionally lead one to write slower code. For example, suppose a fixed set of 100 items out of which a variable selection of 10 or 15 is made. Suppose that a program's time-critical loop asks many times whether item i
has been selected. A fast data structure to support such a time-critical loop would be an array (or vector or the like) of 100 bools. However, to populate a std::set<size_t>
might be easier to code in C++ than to populate the array. The C++ programmer might prefer the set over the array for this reason.
Of course, whether the slower code is a problem depends on how much service the time-critical loop will see. If it takes an extra half hour to program the array technique, and the total execution-time savings over the life of the program is 0.5 seconds, the set technique is probably preferable. On the other hand, if the total execution-time savings is 30 days, then the array technique may be preferable.
Many similar answers along these lines might be given. Good luck with your interview.
回答7:
A priori not a performance issue, but the LLVM codebase uses neither RTTI nor exceptions because they are considered too costly in terms of code size.