Python太慢了我可以用较低级别和cp脚本重写引擎吗?

2024-09-28 23:10:11 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,首先。这是我的服务器引擎。gilmud.py!在

好吧,这是我之前那篇小说大小的帖子的简短版本。在

上面的链接是我们的MUD的python服务器引擎。注意第73-75行和第359行

self.tickThread = threading.Thread(None, self.runTicks, None, ())
self.tickThread.start()

。。。在

^{pr2}$

你可能会看到一个可怕的方法,我们需要大约100个玩家和2000个暴徒/NPC“生活”。tick()会检查诸如他们是否会移动或捡起物品,或者他们是否在战斗中或被瞄准等等。当然,对玩家来说也是如此,当然,除了一些自动化的东西。在

< >我们有没有办法改写一个部分,或者说,C++中的所有模块都能获得更好的性能?目前,我们所需要的.1秒滴答时间大约是3秒,使用我们现在拥有的方法中的python。在

(此外,我们还尝试了几种不同的线程类型和stackless。什么也做不到)。在

提前感谢您的帮助!欢迎任何建议!在


Tags: 方法py引擎self版本服务器none链接
3条回答

你的代码中有很多低效的地方。在

只查看Person.tick方法:

更换

for spell in self.spellTimers:
            self.spellTimers[spell]['tick'] += 1

^{pr2}$

同样的事情,每个值至少少两个dict查找

更换

^{3}$

for thing in Thing.List.itervalues():
            if thing and "person" in thing.attrs 
                     and "spawner" in thing.attrs:
                    thing.tick()

(好吧,也许速度不会太快,但我更喜欢它)

获取:

from spells import cast,spellmaker

从tick()方法中取出并放入文件的顶部

替换:

#spell cooldown timer
self.timers['cooldown'] -= 1
if self.timers['cooldown'] < 0:
    self.timers['cooldown'] = 0

有:

#spell cooldown timer
self.timers['cooldown'] = max(0, self.timers['cooldown']-1)

你经常这样做。 你有很多代码

^{8}$

第二个if应该是elif如果第一个条件为真,第二个条件永远不会为真。在

请记住,每次访问self.somedict['name']时,您都在进行两次dict查找(开销可能会更大,但这是thum的一个规则)。如果你有一个逐行的dictlookup,你可以通过将它分配给一个“temp”本地变量来加快代码的速度

如果你继续检查你的代码,你将放入一个tweek,就像上面的一个tweek,它将把东西内联起来。很抱歉,我不能把这一切都做完。在

由于您没有发布少量相关的Python代码,所以您应该了解Python的一点是,它允许您以C样式编写代码,而使用等效的Python样式就可以了。通常情况下——而且我还没有看到相关的代码——一种处理数据的旧样式(例如,编写一个列表理解)要比使用一种更为python的样式花费更多的时间。在

你可以通过张贴一个或多个小例子,询问是否有更好的方法来加快进度,从而获得帮助,获得Python式风格的帮助。您还需要对代码进行指令以捕获时间。在

<> P>可以用C++或类似的方法重写部分内容,但是如果你的循环需要3秒来处理2000个左右的项目,那么我认为你可能会遇到一些严重的问题,而不是用Python本身固有的问题。在

因此,首先我想补充另一个答案/它的评论中提出的分析建议-这确实是最好的方法来告诉你的循环中所有的时间都在哪里消失。有一些关于python available here提供的分析器的文档。在

其次,如果您使用的是标准的python发行版,那么如果可能的话,我会考虑远离线程。python的默认实现有一个global interpreter lock,它可以阻止任何解释过的python代码真正并行运行,从而消除了很多首先要处理线程的优点(在某些情况下,实际上会使事情变得更慢)

第三,我可以就你发布的代码提供一些小建议。您最好还是使用探查器来确认我的怀疑(并找到我没有注意到的问题区域—看起来您有很多代码),但我认为这至少会有帮助:

在for循环for thing in Thing.List.values():中,最好调用Thing.List.itervalues()。这将返回值的迭代器,而不是分配一个完整的值列表。分配列表是不必要的,除非你计划在迭代时添加或删除字典,而且如果你所暗示的dict中有大约2000个条目,那么分配列表可能不会太快。这个建议也适用于在代码中迭代字典的其他时候,假设您不打算在迭代时添加/删除条目(使用.iteritems()而不是{},.iterkeys()而不是{})。在

您可能还需要研究一种不同于每次迭代调用time.sleep的计时方法。我可以看到两个问题-主要是time.sleep(.1)实际上不能保证睡眠持续0.1秒,还有一个原因是它没有考虑处理所需的时间长度。例如,假设你的处理用了0.05秒,然后你睡了0.1秒,那么时间间隔实际上是0.15秒-而且这个间隔只会随着处理变得更加激烈而增大。我没有任何具体的建议,但是在向time.sleep传递一个数字时,至少要考虑处理时间

最后,您可能需要考虑在某个时刻使用code review stack exchange。我不认为有人会想审查你的整个游戏引擎,但它似乎是一个好地方,可以放置你的代码块,你可能需要反馈,或你认为可以改进。在

相关问题 更多 >