vendredi 1 janvier 2021

Trying to convert an if-elseif group to a group of ternaries. Getting "operand types are incompatible ("Node *" and "int")C/C++(42)"

So, for the sake of making my code faster, I was hoping to turn my if-statements into ternaries, as this was the perfect place to do so. This is because ternaries are faster than if statements, due to being branchless. Due to how often this line will run, I wanted to optimize it. The original function:

void Union(Node nodes[], Node &n, Node &u)
{
    Node& nRoot = findRoot(nodes, n.val);
    Node& uRoot = findRoot(nodes, u.val);
    int nRootRank = nodes[nRoot.val.second].rank;
    int uRootRank = nodes[uRoot.val.second].rank;

    if (nRootRank < uRootRank) nodes[nRoot.val.second].parent = &uRoot;
    else if (nRootRank > uRootRank) nodes[uRoot.val.second].parent = &nRoot;
    else if (std::rand() % 2)
    {
        nodes[nRoot.val.second].parent = &uRoot;
        uRoot.rank++;
    }
    else
    {
        nodes[uRoot.val.second].parent = &nRoot;
        nRoot.rank++;
    }
}

And the Branchless version:

void Union(Node nodes[], Node &n, Node &u)
{
    Node& nRoot = findRoot(nodes, n.val);
    Node& uRoot = findRoot(nodes, u.val);
    int nRootRank = nodes[nRoot.val.second].rank;
    int uRootRank = nodes[uRoot.val.second].rank;

    (nRootRank < uRootRank) ? nodes[nRoot.val.second].parent = &uRoot : 
    (
        (nRootRank > uRootRank) ? nodes[uRoot.val.second].parent = &nRoot : 
        (
            (std::rand() % 2) ? (nodes[nRoot.val.second].parent = &uRoot, uRoot.rank++) : 
            (
                (nodes[uRoot.val.second].parent = &nRoot, nRoot.rank++) 
            )
        )
    );
}

The problem I run into is that the colon in '(nRootRank > uRootRank) ? nodes[uRoot.val.second].parent = &nRoot : ' says "operand types are incompatible ("Node *" and "int")C/C++(42)" despite that from what I can see, the ternary shouldn't have any problems. Any ideas why it gives that message? And no, for those that go directly to "if is better than ternary" no, it's not, except in the few cases where there's a optimized version hardcoded into c++. If you want info on why, look into banchless programming.

Aucun commentaire:

Enregistrer un commentaire