Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何优化该算法_C++_Performance_Algorithm_Optimization - Fatal编程技术网

C++ 如何优化该算法

C++ 如何优化该算法,c++,performance,algorithm,optimization,C++,Performance,Algorithm,Optimization,我需要帮助加快这段代码的速度: UnitBase* Formation::operator[](ushort offset) { UnitBase* unit = 0; if (offset < itsNumFightingUnits) { ushort j = 0; for (ushort i = 0; i < itsNumUnits; ++i) { if (unitSetup[i] == UNIT_ON_FRONT) { if (j == o

我需要帮助加快这段代码的速度:

UnitBase* Formation::operator[](ushort offset)
{
 UnitBase* unit = 0;
 if (offset < itsNumFightingUnits)
 {
  ushort j = 0;
  for (ushort i = 0; i < itsNumUnits; ++i)
  {
   if (unitSetup[i] == UNIT_ON_FRONT)
   {
    if (j == offset)
     unit = unitFormation[i];
    ++j;
   }
  }
 }
 else
  throw NotFound();
 return unit;
}
UnitBase*Formation::operator[](ushort offset)
{
单位基数*单位=0;
if(偏移量<其NumFightingUnits)
{
ushort j=0;
对于(ushort i=0;i
因此,为了提供一些背景知识,我有一个类
Formation
,它包含一个指向
UnitBase
对象的指针数组,称为
UnitFormation
UnitBase*
数组有一个大小相等的数字数组,表示每个相应的UnitBase对象的状态,称为
UnitSetup

我重载了
[]
操作符,以便只返回指向那些具有特定状态的UnitBase对象的指针,因此如果我请求
itsFormation[5]
,函数不一定返回
UnitFormation[5]
,而是返回UnitFormation的第五个元素,该元素在前面具有状态
UNIT\u

我已经尝试过使用上面的代码,但是根据我的分析器,这花费了太多的时间。这是有意义的,因为算法必须在返回请求的指针之前对所有元素进行计数

我是否需要彻底重新思考整个问题,还是可以更快地解决


提前感谢。

一个快速优化方法是在找到单元后立即返回,而不是继续迭代所有剩余单元,例如

if (j == offset)
 unit = unitFormation[i];
变成

if (j == offset)
 return unitFormation[i];
当然,这只在您正在寻找的单元朝向单元形成序列的前端时才有帮助,但这样做很简单,有时确实有帮助

对于每个状态,一个更复杂但更有效的方法是建立并维护一个具有该状态的单位的链接列表。您可以与单元的主数组并行执行此操作,并且链表的内容将是指向主单元数组的指针,因此您不会复制单元数据。然后,要在一个状态中找到一个给定的偏移量,您可以遍历链表的
offset
th节点,而不是遍历每个单元

将其设置为双链接列表并保留尾部指针将允许您查找具有高偏移量的元素,就像查找低偏移量的元素一样快(从末尾开始并向后)


但是,如果有许多单元具有相同的状态,并且您正在寻找偏移量接近中间的单元,那么这仍然会很慢。

重新设计代码以维护“前面的单元”表怎么样?不管这意味着什么,听起来很有趣:-)。如果该部分确实被查询了很多,并且没有经常修改,那么您将节省一些时间。与检查完整单元列表的全部或部分不同,您将立即得到结果


注意:
int
应该为您的CPU使用最自然的类型,因此使用ushorts。

除了一些人提出的其他建议外,您可能希望查看是否有任何对该函数的调用是不必要的,并消除这些调用点。例如,如果您看到在不可能更改结果的情况下重复调用此函数。最快的代码是从不运行的代码。

是否可以按前面的状态单位对数据进行排序(或插入排序的数据)?这将使功能变得微不足道。

一个单元的状态多久会改变一次?也许您应该保留一个具有适当状态的单元列表,并且只在状态更改时更新该列表

如果有必要将状态更改的成本降至最低,您可以保留一个阵列,其中说明前256个单元中有多少个具有特定状态,接下来256个单元中有多少个具有特定状态,等等。在第n个“良好”单元的256个插槽内,可以以扫描单元的256倍速度扫描阵列。更改单元的状态只需要增加或减少一个阵列插槽


考虑到不同的使用模式,可以使用其他方法来平衡更改单元状态的成本和查找单元的成本。

这应该不会有太大的影响,但是您可以检查程序集,查看
itsNumFightingUnits
itsnumnits
是否在每次循环迭代中加载,或者是否将它们放入寄存器中。如果每次都加载临时变量,请尝试在函数开头添加临时变量

对于最后一点,如果定期抛出异常,那么切换到返回错误代码可能是值得的。这是一个更丑陋的代码,但缺少堆栈跳转可能是一个很大的帮助。在游戏开发中,关闭异常和RTTI是很常见的。

问题之一可能是调用此函数的频率太高。假设单位面积在单位面积上的比例为常数,则复杂度为线性。但是,如果从循环中调用运算符,则复杂性将上升到O(N^2)


相反,如果您返回类似于
boost::filter\u迭代器的内容,则可以提高需要在单元上进行迭代的算法的效率。

您比自己更出色(每个人有时都会这样做)。你已经做了一个简单的问题O(N^2)。在你重载操作符之前,想想你要做什么

在回应评论时增加:

尝试备份到一个更简单的语言,比如C,或者C++的C子集。忘掉抽象、集合类和所有这些。看看你的程序需要做什么,并以此来思考你的算法。然后,如果您可以通过使用容器类和重载来简化它,而不需要让它做更多的工作,那么就开始吧。大多数性能问题都是由简单问题引起的,并通过尝试使用所有花哨的想法使其复杂化

例如,你正在服用t
UnitBase* Formation::operator[](ushort offset)
{
    if (offset < numFightingUnits)
        return unitFormation[offset]->getUnit();
    else
        return NULL;
}