Python太慢-我可以用低级脚本和cp脚本重写引擎吗?
所以,首先。这是我的服务器引擎 好的,这是我之前的小说大小的文章的一个缩略版本 上面的链接是我们的MUD的python服务器引擎。注意第73-75行和第359行Python太慢-我可以用低级脚本和cp脚本重写引擎吗?,python,process,mud,Python,Process,Mud,所以,首先。这是我的服务器引擎 好的,这是我之前的小说大小的文章的一个缩略版本 上面的链接是我们的MUD的python服务器引擎。注意第73-75行和第359行 self.tickThread = threading.Thread(None, self.runTicks, None, ()) self.tickThread.start() 你可能会看到一种可怕的方法,我们需要大约100名玩家和2000名怪物/NPC的生命。勾号()会检查玩家是否会移动或拾取物品,或者他们是否在战斗中或成为目标
self.tickThread = threading.Thread(None, self.runTicks, None, ())
self.tickThread.start()
你可能会看到一种可怕的方法,我们需要大约100名玩家和2000名怪物/NPC的生命。勾号()会检查玩家是否会移动或拾取物品,或者他们是否在战斗中或成为目标,等等。当然,玩家也是如此,除了一些自动操作的东西
< >我们有没有办法改写一个部分,或者说,C++中的所有模块都能获得更好的性能?目前,我们所需要的.1秒时间大约为3秒,使用python的方法就是我们现在使用的方法
(此外,我们还尝试了几种不同的线程类型和stackless。没有任何效果)
提前感谢您的帮助!欢迎任何意见 由于您没有发布少量相关Python代码,因此您应该了解Python的一点是,它将允许您以C风格编写代码,而使用等效的Python风格就可以了。通常情况下——我也没有看到相关的代码——一种较旧的处理数据的方式,而不是编写列表理解,将比使用更具python风格的方式花费更多的时间
你可以通过发布一个或多个小例子,询问是否有更好的方法来加快速度,从而获得Python风格的帮助——顺便说一句,我需要很多帮助。您还需要为代码添加工具以捕获时间。因为您没有发布少量相关的Python代码,关于Python,您应该知道的一件事是,它将允许您以C风格编写代码,而使用等效的Python风格就可以了。通常情况下——我也没有看到相关的代码——一种较旧的处理数据的方式,而不是编写列表理解,将比使用更具python风格的方式花费更多的时间
你可以通过发布一个或多个小例子,询问是否有更好的方法来加快速度,从而获得Python风格的帮助——顺便说一句,我需要很多帮助。你也可以用你的代码来捕获时间。< P> >可以用C++或类似的方法重写它的一部分,但是如果你的循环需要3秒来处理2000个左右的项目,那么我认为你可能会对你编码的东西有一些严重的问题,而不是Python本身固有的问题。 因此,首先,我想支持在另一个答案/它的评论中提出的评测建议-这确实是告诉你的循环中所有时间都消失在哪里的最好方法。有一些关于python提供的分析器的文档
第二,如果你使用标准的Python分布,那么如果可能的话,我会考虑远离线程。python的默认实现有一个阻止任何解释过的python代码真正并行运行的机制,从一开始就消除了使用线程的许多优点(在某些情况下实际上会使事情变得更慢)
第三,我可以就您发布的代码提供一些小建议。您最好还是使用探查器来确认我的怀疑(并找到我没有注意到的问题区域-看起来您有很多代码),但我认为这可能至少会有帮助: 在for循环中,对于thing.List.values()中的thing,您最好调用thing.List.itervalues()
。这将返回值的迭代器,而不是分配完整的值列表。分配列表是不必要的,除非您计划在迭代字典时添加或删除它,如果dict中有2000个左右的条目,可能不会太快。此建议也适用于在代码中迭代字典的其他时间,假设您不打算在迭代时添加/删除条目(使用.iteritems()
而不是.items()
,.iterkeys()
而不是.keys()
)
除了每次迭代调用time.sleep
之外,您可能还需要研究一种不同的计时方法。我可以看到它有两个问题-主要是time.sleep(.1)
实际上不能保证睡眠将持续0.1秒,而且还因为它没有考虑处理所需的时间长度。例如,假设你的处理时间为0.05秒,然后你睡眠了0.1秒,那么两个节拍之间实际上有0.15秒的间隔,而这个间隔只会随着处理的强度增加而增大。我没有任何具体的建议,但在将数字传递到time.sleep
<>最后,您可能需要考虑在某个时间点使用。我不认为任何人都想复习你的整个游戏引擎,但是它似乎是一个放置代码的好地方,你可能需要反馈,或者你认为可以改进。 < P> >可以用C++或类似的方法改写它的部分内容。但是,如果您的循环需要3秒钟来处理2000个左右的项目,那么我认为更有可能您在编码方式上遇到了一些严重问题,而不是python本身固有的问题
因此,首先,我想支持在另一个答案/它的评论中提出的评测建议-这确实是告诉你的循环中所有时间都消失在哪里的最好方法。有一些关于python提供的分析器的文档
第二,如果你使用标准的Python分布,那么如果可能的话,我会考虑远离线程。python的默认实现具有防止任何解释性py的
def runTicks(self):
while self.running:
time.sleep(.1)
for thing in Thing.List.values():
if thing:
if "person" in thing.attrs:
if "spawner" in thing.attrs:
thing.tick()
for spell in self.spellTimers:
self.spellTimers[spell]['tick'] += 1
for spell_timer in self.spellTimers.itervalues():
spell_timer['tick'] += 1
for thing in Thing.List.values():
if thing:
if "person" in thing.attrs:
if "spawner" in thing.attrs:
thing.tick()
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
#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)
#Check if self is doing ranged attack, and then increase timer (ready their weapon)
self.timers['ranged'] += 1
if self.timers['ranged'] >= int((self.stats['dex']*-1.1)+60+2):
self.timers['ranged'] = int((self.stats['dex']*-1.1)+60+1)
if self.timers['ranged'] == int((self.stats['dex']*-1.1)+60):
self.timers['ranged'] = int((self.stats['dex']*-1.1)+60+1)