我有一个要提高性能的游戏(使用pygame)。我注意到当我的fps较低时,游戏最多仅使用20%的CPU,是否可以使用线程来利用更多的CPU?
我已经尝试实现线程,但是似乎运气不好,我们将提供一些帮助。
此功能是造成延迟的原因:
def SearchFood(self):
if not self.moving:
tempArr = np.array([])
for e in entityArr:
if type(e) == Food:
if e.rect != None and self.viewingRect != None:
if self.viewingRect.colliderect(e.rect):
tempArr = np.append(tempArr, e)
if tempArr.size > 0:
self.nearestFood = sorted(tempArr, key=lambda e: Mag((self.x - e.x, self.y - e.y)))[0]
def SearchFood(self):
if not self.moving:
s_arr = sorted(entityArr, key=lambda e: math.hypot(self.x - e.x, self.y - e.y))
for e, i in enumerate(s_arr):
if type(e) != Food:
self.nearestFood = None
else:
self.nearestFood = s_arr[i]
break
我会仔细查看整个实体列表,并在该实体是食物以及与要吃所述食物的事物之间的距离之后进行排序。问题是实体数组的长度为500个(或更多)元素,因此要花很长时间才能遍历和排序。然后要补救,我想通过线程使用更多的CPU。
如果有帮助,请参见以下完整脚本:https://github.com/Lobsternator/Game-Of-Life-Esque.git
答案 0 :(得分:1)
在Python中,线程化不会增加已使用内核的数量。您必须改用多重处理。
doc:https://docs.python.org/3.7/library/multiprocessing.html#multiprocessing.Manager
答案 1 :(得分:1)
Python中的多线程几乎是无用的(对于此类CPU密集型任务),而多处理虽然可行,但需要在进程之间进行昂贵的数据封送处理或精心设计。我认为这两个都不适合您的情况。
但是,除非您的游戏中有大量对象,否则您不需要为场景使用多个核心。这个问题似乎更多是算法复杂性之一。
您可以通过多种方式提高代码的性能:
O(n)
)查找最近的食物实体,而不是按距离对所有食物进行排序(O(n*logn)
)。
例如您可以得到类似以下内容的
def find_nearest_food(self):
food_entities = self._entities_by_type[Food]
nearest_food = min(food_entities, key=lambda entity: distance_sq(self, entity))
return nearest_food
def distance_sq(ent1, ent2):
# we don't need an expensive square root operation if we're just comparing distances
dx, dy = (ent1.x - ent2.x), (ent1.y - ent2.y)
return dx * dx + dy * dy
您可以通过将实体位置保持为NumPy向量而不是单独的x
和y
属性来进一步优化,这将允许您使用NumPy运算来计算距离,例如distance_sq = (ent1.pos - ent2.pos)**2
或仅np.linalg.norm
用于常规距离计算。这对于其他向量算术运算也可能有用。