gpt4 book ai didi

c++ - 我如何在考虑性能的情况下重构此代码?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:54:45 25 4
gpt4 key购买 nike

我有一个性能非常重要的方法(我知道过早的优化是万恶之源。我知道我应该并且我确实分析了我的代码。在这个应用程序中,我每节省十分之一秒就是一个巨大的胜利。 ) 此方法使用不同的启发式方法来生成和返回元素。启发式算法是按顺序使用的:使用第一个启发式算法,直到它不再返回元素,然后使用第二个启发式算法,直到它不再可以返回元素,依此类推,直到使用完所有启发式算法。在每次调用该方法时,我都使用一个开关来移动到正确的启发式。这很丑陋,但效果很好。这是一些伪代码

class MyClass
{
private:
unsigned int m_step;
public:
MyClass() : m_step(0) {};

Elem GetElem()
{
// This switch statement will be optimized as a jump table by the compiler.
// Note that there is no break statments between the cases.
switch (m_step)
{
case 0:
if (UseHeuristic1())
{
m_step = 1; // Heuristic one is special it will never provide more than one element.
return theElem;
}

m_step = 1;

case 1:
DoSomeOneTimeInitialisationForHeuristic2();
m_step = 2;

case 2:
if (UseHeuristic2())
{
return theElem;
}

m_step = 3;

case 3:
if (UseHeuristic3())
{
return theElem;
}
m_step = 4; // But the method should not be called again
}

return someErrorCode;
};
}

正如我所说,这行得通而且效率很高,因为在每次调用时,执行都会跳转到它应该跳转到的地方。如果启发式无法提供元素,则 m_step 递增(因此下次我们不再尝试此启发式)并且因为没有 break 语句,将尝试下一个启发式。另请注意,某些步骤(如步骤 1)从不返回元素,而是对下一个启发式进行一次性初始化。

初始化没有全部预先完成的原因是它们可能永远不需要。 GetElem 在返回一个元素后总是有可能(并且很常见)不再被调用,即使仍然有它可以返回的元素。

虽然这是一个高效的实现,但我发现它真的很难看。案例陈述是一个黑客;不间断地使用它也是骇人听闻的;该方法变得非常长,即使每个启发式都封装在它自己的方法中。

我应该如何重构这段代码,使其更具可读性和优雅性,同时尽可能保持高效?

最佳答案

将每个启发式包装在一个迭代器中。在第一次调用 hasNext() 时将其完全初始化。然后将所有迭代器收集到一个列表中,并使用 super 迭代器遍历所有迭代器:

boolean hasNext () {
if (list.isEmpty()) return false;

if (list.get(0).hasNext()) return true;

while (!list.isEmpty()) {
list.remove (0);
if (list.get(0).hasNext()) return true;
}
return false;
}
Object next () {
return list.get (0).next ();
}

注意:在这种情况下,链表可能比 ArrayList 快一点点,但您仍应检查一下。

[编辑] 将“将每个”更改为“包装每个”以使我的意图更加清晰。

关于c++ - 我如何在考虑性能的情况下重构此代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1980571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com