C ++ Performance Analysis (iv): Impact of Inheritance on Performance

Source: Internet
Author: User

C ++ Performance Analysis (iv): Impact of Inheritance on Performance
Inheritance is an important feature of OOP. Although many colleagues in the industry do not like inheritance, correct use of inheritance is an important design decision at the application and architecture layers. How does the extensive use of inheritance, especially in std container-like, affect program performance? In my personal experience, constructor has a great impact on creating classes with deep inheritance chains. If the application permits, it is best to use a base class without a constructor. The following is an example: struct _ declspec (novtable) ITest1 {virtual void AddRef () = 0; virtual void Release () = 0; virtual void DoIt (int x) = 0;}; class CTest: public ITest1 {int ref; public: inline CTest () {ref = 0;} inline void AddRef () {++ ref ;} inline void Release () {-- ref;} inline void DoIt (int x) {ref * = x;} inline void AddRef2 () {++ ref;} inline void Release2 () {-- ref;} inline void DoIt2 (int x) {r Ef * = x;} static void TestPerf (int loop) ;}; this is a dummy program, but it is common in COM. If we want to create and use CTest in large quantities, experienced programmers should see that ITest1 does not need constructor at all. According to the C ++ statement, ITest1 is a non-simple constructor because of its virtual functions, the only purpose is to set the vtbl (virtual function table) of itest1 ). However, the only role of an interface is to be inherited, so its vtbl must be set by its inherited class. In this case, it is not necessary to generate a constructor. Microsoft realized this when designing ATL and launched its own solution to avoid the defect of C ++ official SPEC: VC ++ provided the class modifier of novtable and told Compilation: I don't need your constructor. however, my test results in VS 2010 are disappointing: the constructor of ITest1 is still generated, but it does not assign a value to vtbl, this improves the performance of the base class structure. Let's take a look at the impact of this "useless constructor" on performance. We have the right to come up with another ITestPOD (POD means "data") that does not require virtual functions for comparison: struct ITest1POD {inline void AddRef () {} inline void Release () {} inline void DoIt (int x) {}}; of course, ITestPOD cannot be fully used as an interface (virtual functions must be used for interfaces), just for testing. Then, we design an inheritance class, which is exactly the same as the above CTest function: class CTestPOD: public ITest1POD {int ref; public: inline CTestPOD () {ref = 0 ;} inline void AddRef () {++ ref;} inline void Release () {-- ref;} inline void DoIt (int x) {ref * = x ;}}; our goal is to use this CTestPOD to compare Apple and apple with CTest: void CTest: TestPerf (int loop) {clock_t begin = clock (); for (int I = 0; I <loop; ++ I) // loop1 {CTestPOD testPOD; // line1 testPOD. addRef (); test POD. doIt (0); testPOD. release ();} clock_t end = clock (); printf ("POD time: % f \ n", double (end-begin)/CLOCKS_PER_SEC); begin = clock (); for (int I = 0; I <loop; ++ I) // loop2 {CTest test; // line2 test. addRef2 (); test. doIt2 (0); test. release2 () ;}end = clock (); printf ("Interface time: % f \ n", double (end-begin)/CLOCKS_PER_SEC );} the only difference between loop1 and loop2 is line1 and line2. To avoid using virtual functions, I specially prepared AddRef2 and Do for CTest. It2, Release2, three identical but non-virtual functions, in order to follow a major principle of Performance Testing: compare apple to apple. I set the loop to 0.1 million. The test results show that loop2 is about 20% slower than loop1. From the generated code, the only difference is that the constructor of CTest calls the constructor of itest1. This constructor has no function, but it occupies many CPU cycles. A good compilation should be able to crop this constructor, Which is searched by ourselves. In summary, when applying inheritance, removing useless constructor in the base class will significantly affect the performance of a large number of constructed objects. Unfortunately, Microsoft's _ declspec (novtable) class modifier does not provide any help to solve this problem. In the design of object applications with massive storage, we should try to use pods as the base class to avoid performance vulnerabilities as obvious as the CTest class above.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.