C++ 找到其他节点的最快方法
我有一个三角形类,带有指向节点(n0、n1、n2)的指针。我还有一个方法,在传递两个节点指针(a,b)时返回“other”节点。目前的执行情况如下:C++ 找到其他节点的最快方法,c++,c,performance,C++,C,Performance,我有一个三角形类,带有指向节点(n0、n1、n2)的指针。我还有一个方法,在传递两个节点指针(a,b)时返回“other”节点。目前的执行情况如下: if ( n0 == a && n1 == b ) { return n2; } else if ( n0 == b && n1 == a ) { return n2; } else if ( n1 == a && n2 == b ) { return n0; } else i
if ( n0 == a && n1 == b )
{
return n2;
}
else if ( n0 == b && n1 == a )
{
return n2;
}
else if ( n1 == a && n2 == b )
{
return n0;
}
else if ( n1 == b && n2 == a )
{
return n0;
}
else if ( n0 == a && n2 == b )
{
return n1;
}
else if ( n0 == b && n2 == a )
{
return n1;
}
else
{
assert( 0 );
}
return NULL;
哪种方法有效,但可能不是最好的。在分析之后,我的程序实际上在这个例程中花费了可测量的时间,因此值得花一些时间进行优化。然而,我不太熟悉编译器将要做的优化,所以我不确定这是否是多余的
节点没有特定的顺序,因此平均而言,它必须执行3.5个复合比较
另一种方法是:
if ( n0 == a )
{
if ( n1 == b )
{
return n2;
}
else if ( n2 == b )
{
return n1;
}
return NULL;
}
else if ( n1 == a )
{
if ( n0 == b )
{
return n2;
}
else if ( n2 == b )
{
return n0;
}
return NULL;
}
else if ( n2 == a ) // Theoretically redundant. Kept for safety.
{
if ( n0 == b )
{
return n1;
}
else if ( n1 == b )
{
return n0;
}
return NULL;
}
return NULL;
在简单的比较中,平均值为3.5。这会更快吗?还是编译器会使它们保持相同
有没有更快的办法
我知道我可以消除多余的if。在第一种情况下,它将平均复合比较减少到3.33。在第二种情况下,它将平均值拉低到3.0个简单比较
我可以消除所有其他的,因为每个真正的代码块都包含一个返回。然而,我真的觉得编译器应该足够聪明,能够自己处理任何增益。任何与自身异或的东西都将为零,因此如果给你三个中的两个,你只需执行
n0^n1^n2^a^b
就可以找到剩下的一个。这很值得一个解释性的评论,但如果速度很重要,那几乎肯定是你最快的选择。“这会更快吗”-分析一下,发现你的代码似乎可以工作。对于需要优化的工作代码,两个代码示例都考虑了a
和/或b
可能根本不在节点中的可能性。这真的是一种必须得到支持的可能性吗?或者a
和b
是否始终保证位于节点中?“如果你能提供这种保证,那么你就可以剔除一半的比较。”雷米在分析之前提问,我希望找到理解和洞察力,而不仅仅是经验证据。我相信我们可以保证这段代码永远不会返回NULL。@很抱歉在错误的位置询问。通过适当的强制转换,它似乎可以工作return(Node*)((uintpttr_t)n0^(uintpttr_t)n1^(uintpttr_t)n2^(uintpttr_t)a^(uintpttr_t)b)代码>。这似乎很难击败。假设a
和b
都是指向正在检查的三角形内部节点的指针。如果它们是指向外部节点的指针,这种方法就失败了。虽然这是这个问题的最佳答案,但它仍然没有回答更一般的问题——复合条件句比简单条件句花费的时间要长得多吗?是否值得手动扩展这样的代码,以获得不重复检查的简单条件?