What is the effect of ordering if…else if statements by probability?

后端 未结 10 1812
花落未央
花落未央 2020-12-07 13:39

Specifically, if I have a series of if...else if statements, and I somehow know beforehand the relative probability that each statement will evalua

10条回答
  •  感动是毒
    2020-12-07 14:07

    I made up the following test to time the execution of two different if...else if blocks, one sorted in order of probability, the other sorted in reverse order:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    int main()
    {
        long long sortedTime = 0;
        long long reverseTime = 0;
    
        for (int n = 0; n != 500; ++n)
        {
            //Generate a vector of 5000 random integers from 1 to 100
            random_device rnd_device;
            mt19937 rnd_engine(rnd_device());
            uniform_int_distribution rnd_dist(1, 100);
            auto gen = std::bind(rnd_dist, rnd_engine);
            vector rand_vec(5000);
            generate(begin(rand_vec), end(rand_vec), gen);
    
            volatile int nLow, nMid, nHigh;
            chrono::time_point start, end;
    
            //Sort the conditional statements in order of increasing likelyhood
            nLow = nMid = nHigh = 0;
            start = chrono::high_resolution_clock::now();
            for (int& i : rand_vec) {
                if (i >= 95) ++nHigh;               //Least likely branch
                else if (i < 20) ++nLow;
                else if (i >= 20 && i < 95) ++nMid; //Most likely branch
            }
            end = chrono::high_resolution_clock::now();
            reverseTime += chrono::duration_cast(end-start).count();
    
            //Sort the conditional statements in order of decreasing likelyhood
            nLow = nMid = nHigh = 0;
            start = chrono::high_resolution_clock::now();
            for (int& i : rand_vec) {
                if (i >= 20 && i < 95) ++nMid;  //Most likely branch
                else if (i < 20) ++nLow;
                else if (i >= 95) ++nHigh;      //Least likely branch
            }
            end = chrono::high_resolution_clock::now();
            sortedTime += chrono::duration_cast(end-start).count();
    
        }
    
        cout << "Percentage difference: " << 100 * (double(reverseTime) - double(sortedTime)) / double(sortedTime) << endl << endl;
    }
    

    Using MSVC2017 with /O2, the results show that the sorted version is consistently about 28% faster than the unsorted version. Per luk32's comment, I also switched the order of the two tests, which makes a noticeable difference (22% vs 28%). The code was run under Windows 7 on an Intel Xeon E5-2697 v2. This is, of course, very problem-specific and should not be interpreted as a conclusive answer.

提交回复
热议问题