简体   繁体   中英

C++ function performance issue

I met a C++ function performance issue, testing with the code below. The implementations of the queryInterface and queryInterface1 are almost same. The only difference is that queryInterface calling classType function, and classType function calling classType1 , queryInterface1 call classType1 directly. The performance of queryInterface1 is bad, it takes twice times as long as queryInterface . What's the problem of queryInterface1 , and Why? Compiled with MSVC. See the output in console:

time cost of queryInterface(): 2453

time cost of queryInterface1(): 4961

#include <string>
#include <time.h>
#include <iostream>
#include <unordered_map>

using namespace std;

namespace
{
    int find(const string& name)
    {
        return 0;
    }

    class A
    {
    public:
        static int classType();
        static int classType1();
        virtual void* queryInterface(int id) const
        {
            if (A::classType() == id)
                return const_cast<A*>(this);

            return nullptr;
        }
        virtual void* queryInterface1(int id) const
        {
            if (A::classType1() == id)
                return const_cast<A*>(this);

            return nullptr;
        }
    };

    int A::classType()
    {
        static int s_classType = classType1();
        return s_classType;
    }

    int A::classType1()
    {
        static int s_classType = find("A");
        return s_classType;
    }
}

int main()
{
    clock_t start, stop;
    const size_t count = 1000000000;

    A* pA = new A;
    start = clock();
    for (size_t i = 0; i < count; i++)
    {
        pA->queryInterface(A::classType());
    }
    stop = clock();
    cout << "time cost of queryInterface(): " << stop - start << endl;

    start = clock();
    for (size_t i = 0; i < count; i++)
    {
         pA->queryInterface1(A::classType1());
    }
    stop = clock();
    cout << "time cost of queryInterface1(): " << stop - start << endl;

    return 0;
}

The performance difference is due to the compiler setting up security checks within the call of A::classType1 . These are set up every call, even though it is only be really needed for the one time the find function is called.

The security checks determine if the stack has been overwritten, potentially clobbering the stack frame, including the return address.

Changing the initial value if s_classType to be a constant integer, instead of the call to find , results in a much faster execution of the queryInterface1 calls.

The security checks can be disabled with the /GS- compiler option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM