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

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的生命。勾号()会检查玩家是否会移动或拾取物品,或者他们是否在战斗中或成为目标

所以,首先。这是我的服务器引擎

好的,这是我之前的小说大小的文章的一个缩略版本

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

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)