C语言和C++哪个效率更高?老司机3句话告诉你答案
1.INDEXChapter 25: WrITING EFFICIENT C++ 881 Overview of Performance and Efficiency 882 Two Approaches to Efficiency 882 Two Kinds of Programs 882 Is C++ an Inefficient Language? 882 Language-Level Efficiency 883 Handle Objects Efficiently 884 Pass-by-Reference 884 Return-by-Reference 886 Catch Exceptions by Reference 886 Use Move Semantics 886 Avoid Creating Temporary Objects 886 The Return-Value Optimization 887 Pre-allocate Memory 888 Use Inline Methods and Functions 888 Design-Level Efficiency 889 Cache Where Necessary 889 Use Object Pools 890 An Object Pool Implementation 891 Using the Object Pool 893 Profiling 894 Profiling Example with gprof 895 First Design Attempt 895 Profiling the First Design Attempt 898 Second Design Attempt 900 Profiling the Second Design Attempt 901 Profiling Example with Visual C++ 2017 902 Summary 9072. OVERVIEW OF PERFORMANCE AND EFFICIENCY
Before delving further into the details, it’s helpful to define the terms performance and efficiency,as used in this book. The performance of a program can refer to several areas, such as speed,memory usage, disk access, and network use. This chapter focuses on speed performance. The term efficiency, when applied to programs, means running without wasted effort. An efficient program completes its tasks as quickly as possible within the given circumstances. A program can be efficient without being fast, if the application domain is inherently prohibitive to quick execution. Note that the title of this chapter, “Writing Efficient C++,” means writing programs that run efficiently, not efficiently writing programs. That is, the time you learn to save by reading this chapter will be your users’, not your own! NOTE An efficient, or high-performance, program runs as fast as is possible for the particular tasks.2.1 Two Approaches to Efficiency
Language-level efficiency involves using the language as efficiently as possible, for example, pass- ing objects by reference instead of by value. However, this will only get you so far. Much more important is design-level efficiency, which includes choosing efficient algorithms, avoiding unneces- sary steps and computations, and selecting appropriate design optimizations. More often than not, optimizing existing code involves replacing a bad algorithm or data structure with a better, more efficient one.2.2 Two Kinds of Programs
As I’ve noted, efficiency is important for all application domains. Additionally, there is a small subset of programs, such as system-level software, embedded systems, intensive computational applications, and real-time games, that require extremely high levels of efficiency. Most programs don’t.Unless you write those types of high-performance applications, you probably don’t need to worry about squeezing every ounce of speed out of your C++ code. Think of it as the difference between building normal family cars and building sports cars. Every car must be reasonably efficient, but sports cars require extremely high performance. You wouldn’t want to waste your time optimizing family cars for speed when they’ll never go faster than 70 miles per hour.2.3 Is C++ an Inefficient Language?
C programmers often resist using C++ for high-performance applications. They claim that the language is inherently less efficient than C or a similar procedural language because C++ includes high-level concepts, such as exceptions and virtual methods. However, there are problems with this argument. When discussing the efficiency of a language, you must separate the performance capabilities of the language itself from the effectiveness of its compilers at optimizing it, that is, you cannot ignore the effect of compilers. Recall that the C or C++ code you write is not the code that the computer executes. A compiler first translates that code into machine language, applying optimizations in the process. This means that you can’t simply run benchmarks of C and C++ programs and compare the results. You’re really comparing the compiler optimizations of the languages, not the languages themselves. C++ compilers can optimize away many of the high-level constructs in the language to generate machine code similar to, or even better than, the machine code generated from a comparable C program. These days, much more research and development is poured into C++ compilers than into C compilers, so C++ code might actually get better optimized and might run faster than C code. Critics, however, still maintain that some features of C++ cannot be optimized away. For example,as Chapter 10 explains, virtual methods require the existence of a vtable and an additional level of indirection at run time, possibly making them slower than regular non-virtual function calls. However, when you really think about it, this argument is unconvincing. Virtual method calls provide more than just a function call: they also give you a run-time choice of which function to call. A comparable non-virtual function call would need a conditional statement to decide which function to call. If you don’t need those extra semantics, you can use a non-virtual function. A general design rule in the C++ language is that “if you don’t use a feature, you don’t need to pay for it.” If you don’t use virtual methods, you pay no performance penalty for the fact that you could use them. Thus, non-virtual function calls in C++ are identical to function calls in C in terms of performance.However, because virtual function calls have such a tiny overhead, I recommend making all your class methods, including destructors but not constructors, virtual for all your non-final classes. Far more important, the high-level constructs of C++ enable you to write cleaner programs that are more efficient at the design level, are more readable, more easily maintained, and avoid accumulating unnecessary and dead code. I believe that you will be better served in your development, performance, and maintenance by choosing C++ instead of a procedural language such as C. There are also other higher-level object-oriented languages such as C# and Java, both of which run on top of a virtual machine. C++ code is executed directly by a CPU; there is no such thing as a virtual machine to run your code. C++ is closer to the hardware, which means that in most cases it runs faster than languages such as C# and Java.3.LANGUAGE-LEVEL EFFICIENCY
Many books, articles, and programmers spend a lot of time trying to convince you to apply language- level optimizations to your code. These tips and tricks are important, and can speed up your programs in some cases. However, they are far less important than the overall design and algorithm choices in your program. You can pass-by-reference all you want, but it won’t make your program fast if you per- form twice as many disk writes as you need to. It’s easy to get bogged down in references and pointers and forget about the big picture. Furthermore, some of these language-level tricks can be performed automatically by good optimiz- ing compilers. You should never spend time optimizing a particular area, unless a profiler, discussed later in this chapter, tells you that that particular area is a bottleneck. That being said, using certain language-level optimizations, such as pass-by-reference, is just consid- ered good coding style. In this book, I’ve tried to present a balance of strategies. So, I’ve included here what I feel are the most useful language-level optimizations. This list is not comprehensive, but is a good start to write optimized code. However, make sure to read, and practice, the design-level efficiency advice that I offer later in this chapter as well. WARNING Apply language-level optimizations judiciously. I recommend making a clean, well-structured design and implementation first. Then use a profiler, and only invest time optimizing those parts that are flagged by a profiler as being a performance bottleneck.
3.1



