【发布时间】:2017-02-18 21:50:35
【问题描述】:
我有一个项目可以处理大量相同类型的对象。
现在我使用List<Person>,但是当我有大约 1 000 000 个项目时,循环遍历这个列表似乎很困难。
在循环中,每个Person都有一个方法被调用,随机生成新的item,也有一些item被删除。
我可以做些什么来优化这个循环? 我应该更改集合类型,还是将项目移至数据库?
这是循环的样子:
while (_worldIsLiving)
{
int beginningPopulation = WorldPopulationNumber;
for (int i = 0; i < beginningPopulation; i++)
{
_worldPopulation[i].InvokeSkills(this);
}
// Remove dead persons
for (int i = 0; i < WorldPopulationNumber;)
{
if (_worldPopulation[i].IsDead()) _worldPopulation.RemoveAt(i);
else i++;
}
WorldCycles++;
if (_hasStopCondition && (WorldPopulationNumber >= WorldMaximumPopulation || WorldPopulationNumber == 0))
Destroy();
}
在_worldPopulation[i].InvokeSkills(this);可以生成新的人。
技能有chanceToBeInvoken和chanceTobeInherited字段。
【问题讨论】:
-
唯一更快迭代的就是普通数组,但这可能只会产生微小的差异。任何优化通常都在循环中的代码中,而不是容器中。要回答这个问题,我们需要更多地了解循环中的代码。
-
当您说“循环遍历此列表很困难”时,您所说的“困难”是什么意思?这就像循环一个只有几个元素的列表一样简单——只是需要更长的时间。
-
项目存储在内存中。
Person有技能列表,每个技能都有机会被调用。主循环中的代码:我调用Person类中调用随机技能的方法。 @MatthewWatson 循环很难,因为在大量项目上,一个循环大约需要一分钟。 @Enigmativity -
似乎很可能关注循环而不是循环中执行的操作是浪费时间。因此,您的问题完全缺乏正确回答的信息。
-
@MarkBenovsky
_worldPopulation.RemoveAt(i)在列表上将是一项昂贵的操作。它涉及将每个后续项目向下分流一个位置,并且您将为每个“死”实例执行多次此操作。对于一个长列表,这将增加相当大的开销,具有 O(n2) 的性能(如果我的 CS 帽子今天戴得正确的话)。只写一个新列表可能会快得多:_worldPopulation = _worldPopulation.Where(p=>!p.IsDead())
标签: c# optimization collections parallel-processing large-data