6
\$\begingroup\$

I have the following program running. It has so far been taking several days straight and has yet to finish. So, I'm just wondering if there is any way it can be optimized or better structured to reduce how long it takes to run (yes, I realize there's a lot of calculations).

struct NumberSets
{
    std::vector<double> vdNums;
    //other code
};

struct NumSetsGamesCommon
{
    std::vector<NumberSets> vGames;
    std::vector<double> vdNums;
    int iSetCount;
};

void RunFoo()
{
    std::vector<NumberSets> inResults; //historical data file.

    const unsigned int iTotalNumPool = 45;
    const unsigned int iNumsWin2Sel = 7;
    const int iFrames2Check = 6;//or 7.

    std::vector<NumSetsGamesCommon> vNumsCommonSets;

    std::vector<bool> vbFrames(iNumsWin2Sel);
    std::fill(vbFrames.begin(), vbFrames.end() - iNumsWin2Sel + iFrames2Check, true);

    do
    {
        std::vector<bool> vNumTotalPools(iTotalNumPool);
        std::fill(vNumTotalPools.begin(), vNumTotalPools.end() - iTotalNumPool + iFrames2Check, true);

        do
        {
            std::vector<double> vdNums2Rotate;
            int id = 0;
            for (int ic = 0; ic < vbFrames.size(); ++ic)
            {
                if (vbFrames.at(ic))
                {
                    for (; id < iTotalNumPool; ++id)
                    {
                        if (vNumTotalPools[id])
                        {
                            vdNums2Rotate.push_back(id);
                            ++id;
                            break;
                        }
                    }
                }
            }

            do
            {
                std::vector<double> vdNums2Check;
                int iPosNum_Rotate = 0;
                for (int ic = 0; ic < vbFrames.size(); ++ic)
                {
                    if (vbFrames.at(ic))
                        vdNums2Check.push_back(vdNums2Rotate.at(iPosNum_Rotate++));
                    else
                        vdNums2Check.push_back(0xff); //filler & not checked against.
                }

                bool bNumSetFound = false;
                std::vector<NumberSets>::iterator itGameSet = inResults.begin();
                for (; itGameSet != inResults.end(); ++itGameSet)
                {
                    bool bSaveNumSet = false;
                    int iFramesChecked = 0;

                    for (int ih = 0; ih < vbFrames.size(); ++ih)
                    {
                        if (vbFrames.at(ih))
                        if (vdNums2Check[ih] == itGameSet->vdNums.at(ih))
                        {
                            ++iFramesChecked;
                        }

                        if (iFramesChecked == iFrames2Check)
                        {
                            bSaveNumSet = true;
                            break;
                        }
                    }

                    if (bSaveNumSet)
                    {
                        if (!bNumSetFound)
                        {
                            NumSetsGamesCommon nsgc;
                            nsgc.vdNums = vdNums2Check;
                            nsgc.iSetCount = 0;
                            vNumsCommonSets.push_back(nsgc);
                            bNumSetFound = true;
                        }
                        vNumsCommonSets.at(vNumsCommonSets.size() - 1).iSetCount += 1;
                        vNumsCommonSets.at(vNumsCommonSets.size() - 1).vGames.push_back(*itGameSet);
                    }
                }
            } while (std::next_permutation(vdNums2Rotate.begin(), vdNums2Rotate.end()));
        } while (std::prev_permutation(vNumTotalPools.begin(), vNumTotalPools.end())); /*rotates through all relevant numbers to use*/
    } while (std::prev_permutation(vbFrames.begin(), vbFrames.end()));
}

The code should be self-explanatory. In case not, though: this code basically compares the movement of each frame between games and collating data for those games where movement/frame match.

I'd prefer to do this without resorting to threads/multithreading.

\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! As making code more efficient is implied with all questions on this site it is better to write a title that says what your code does in a few words. \$\endgroup\$ – Phrancis Feb 19 '16 at 22:44
  • \$\begingroup\$ Thank you, not sure though how I'd better reword title to be honest. Feel free to change. \$\endgroup\$ – ReturnVoid Feb 19 '16 at 22:45
1
\$\begingroup\$
                    if (vbFrames.at(ih))
                    if (vdNums2Check[ih] == itGameSet->vdNums.at(ih))
                    {
                        ++iFramesChecked;
                    }

Just use && for this sort of thing.

                    if (vbFrames.at(ih) && vdNums2Check[ih] == itGameSet->vdNums.at(ih))
                    {
                        ++iFramesChecked;
                    }

As it is right now, the if statement leads to a bit of confusion. With &&, your intent is clearer.

\$\endgroup\$
0
\$\begingroup\$

Well I decided to just re-write main part of it, though this too can likely be improved but least now the program is done in fraction of the time & not taking days/weeks to finish:

struct NumberSets
{
    std::vector<double> vdNums;
    //other code
};

struct NumSetsGamesCommon
{
    std::vector<NumberSets> vGames;
    std::vector<double> vdNums;
    int iSetCount;
};

void RunFoo()
{
    std::vector<NumberSets> inResults; //historical data file.

    const unsigned int iTotalNumPool = 45;
    const unsigned int iNumsWin2Sel = 7;
    const int iFrames2Check = 6;//or 7.

    std::vector<NumSetsGamesCommon> vNumsCommonSets;

    std::vector<NumberSets>::iterator itGameSet1 = inResults.begin();
    for (; itGameSet1 != inResults.end(); ++itGameSet1)
    {
        std::vector<bool> vbFrames(iNumsWin2Sel);
        std::fill(vbFrames.begin(), vbFrames.end() - iNumsWin2Sel + iFrames2Check, true);

        do
        {
            bool bNumSetFound = false;

            std::vector<NumberSets>::iterator itGameSet2 = itGameSet1;
            ++itGameSet2;

            for (; itGameSet2 != inResults.end(); ++itGameSet2)
            {
                bool bSaveNumSet = false;
                int iFramesChecked = 0;

                for (int ih = 0; ih < vbFrames.size(); ++ih)
                {
                    if (vbFrames.at(ih) && itGameSet1->vdNums.at(ih) == itGameSet2->vdNums.at(ih))
                        ++iFramesChecked;

                    if (iFramesChecked == iFrames2Check)
                    {
                        if (itGameSet1 != itGameSet2)
                        {
                            bSaveNumSet = true;
                            break;
                        }
                    }
                }

                if (bSaveNumSet)
                {
                    if (vNumsCommonSets.size() != 0)
                    {
                        //check existing to make sure not done already.
                        //if existing then dont save. otherwise double ups occur.
                        std::vector<NumSetsGamesCommon>::iterator itNumSets = vNumsCommonSets.begin();
                        bool bExitingItem = false;
                        for (; itNumSets != vNumsCommonSets.end(); ++itNumSets)
                        {
                            int iIntegrityCheck = 0;
                            for (int ic = 0; ic < vbFrames.size(); ++ic)
                            {
                                if (vbFrames.at(ic) && itNumSets->vdNums.at(ic) == itGameSet1->vdNums.at(ic))
                                    ++iIntegrityCheck;
                            }
                            if (iIntegrityCheck == iFrames2Check)
                            {
                                for (int ib = 0; ib < itNumSets->vGames.size(); ++ib)
                                {
                                    if (itNumSets->vGames.at(ib).vdNums == itGameSet2->vdNums)
                                    {
                                        bExitingItem = true;
                                        break;
                                    }
                                }
                            }
                        }

                        if (bExitingItem)
                            continue;
                    }

                    if (!bNumSetFound)
                    {
                        NumSetsGamesCommon nsgc;
                        for (int ic = 0; ic < vbFrames.size(); ++ic)
                        {
                            if (vbFrames.at(ic))
                                nsgc.vdNums.push_back(itGameSet1->vdNums.at(ic));
                            else
                                nsgc.vdNums.push_back(0xff);
                        }
                        nsgc.iSetCount = 1;
                        nsgc.vGames.push_back(*itGameSet1);
                        vNumsCommonSets.push_back(nsgc);
                        bNumSetFound = true;
                    }
                    vNumsCommonSets.at(vNumsCommonSets.size() - 1).iSetCount += 1;
                    vNumsCommonSets.at(vNumsCommonSets.size() - 1).vGames.push_back(*itGameSet2);
                }
            }
        } while (std::prev_permutation(vbFrames.begin(), vbFrames.end()));
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.