如何配置Python脚本?

欧拉计画和其余编码竞赛常常有最多的运行时间,或者人们吹嘘他们的特定解决方案的运行速度。 使用Python时,有时这些方法有些繁琐-即在__main__添加计时代码。 html

剖析Python程序须要花费多长时间的好方法是什么? python


#1楼

前一阵子我作了pycallgraph ,它从您的Python代码生成了可视化效果。 编辑:我已经更新了该示例以使其可用于本文撰写时的最新版本3.3。 git

pip install pycallgraph并安装GraphViz以后,您能够从命令行运行它: github

pycallgraph graphviz -- ./mypythonscript.py

或者,您能够分析代码的特定部分: windows

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()

这些都将生成一个pycallgraph.png文件,相似于下图: 服务器

在此处输入图片说明


#2楼

是否曾经想知道python脚本到底在作什么? 输入检查外壳。 经过Inspect Shell,您能够在不中断正在运行的脚本的状况下打印/更改全局变量并运行函数。 如今具备自动完成和命令历史记录(仅在Linux上)。 app

Inspect Shell不是pdb样式的调试器。 socket

https://github.com/amoffat/Inspect-Shell ide

您可使用它(和您的手表)。 svg


#3楼

@Maxy对这个答案的评论帮助了我不少,我认为它应该获得本身的答案:我已经有了cProfile生成的.pstats文件,而且我不想用pycallgraph从新运行,因此我使用了gprof2dot ,而且很漂亮svgs:

$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg

和布莱姆!

它使用点(pycallgraph使用相同的东西),所以输出看起来相似。 个人印象是,尽管gprof2dot丢失的信息更少:

gprof2dot示例输出


#4楼

值得指出的是,使用探查器仅在主线程上有效(默认状况下),若是使用其余线程,则不会从其余线程得到任何信息。 这可能有点麻烦,由于在探查器文档中彻底没有说起。

若是您还想分析线程,则须要查看文档中的threading.setprofile()函数

您也能够建立本身的threading.Thread子类来作到这一点:

class ProfiledThread(threading.Thread):
    # Overrides threading.Thread.run()
    def run(self):
        profiler = cProfile.Profile()
        try:
            return profiler.runcall(threading.Thread.run, self)
        finally:
            profiler.dump_stats('myprofile-%d.profile' % (self.ident,))

并使用该ProfiledThread类而不是标准类。 它可能会给您带来更大的灵活性,可是我不肯定是否值得,特别是若是您使用的是不使用您的类的第三方代码。


#5楼

个人方式是使用yappi( https://code.google.com/p/yappi/ )。 与RPC服务器结合使用时特别有用,在RPC服务器中(甚至仅用于调试),您注册方法以启动,中止和打印性能分析信息,例如:

@staticmethod
def startProfiler():
    yappi.start()

@staticmethod
def stopProfiler():
    yappi.stop()

@staticmethod
def printProfiler():
    stats = yappi.get_stats(yappi.SORTTYPE_TTOT, yappi.SORTORDER_DESC, 20)
    statPrint = '\n'
    namesArr = [len(str(stat[0])) for stat in stats.func_stats]
    log.debug("namesArr %s", str(namesArr))
    maxNameLen = max(namesArr)
    log.debug("maxNameLen: %s", maxNameLen)

    for stat in stats.func_stats:
        nameAppendSpaces = [' ' for i in range(maxNameLen - len(stat[0]))]
        log.debug('nameAppendSpaces: %s', nameAppendSpaces)
        blankSpace = ''
        for space in nameAppendSpaces:
            blankSpace += space

        log.debug("adding spaces: %s", len(nameAppendSpaces))
        statPrint = statPrint + str(stat[0]) + blankSpace + " " + str(stat[1]).ljust(8) + "\t" + str(
            round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + "\t" + str(round(stat[3], 2)) + "\n"

    log.log(1000, "\nname" + ''.ljust(maxNameLen - 4) + " ncall \tttot \ttsub")
    log.log(1000, statPrint)

而后,当程序工做时,您能够随时经过调用startProfiler RPC方法来启动事件探查器,并经过调用printProfiler (或修改rpc方法以将其返回给调用者)将分析信息转储到日志文件中,并得到如下输出:

2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
name                                                                                                                                      ncall     ttot    tsub
2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
C:\Python27\lib\sched.py.run:80                                                                                                           22        0.11    0.05
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\xmlRpc.py.iterFnc:293                                                22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\serverMain.py.makeIteration:515                                                    22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\PicklingXMLRPC.py._dispatch:66                                       1         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.date_time_string:464                                                                                    1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py._get_raw_meminfo:243     4         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.decode_request_content:537                                                                          1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py.get_system_cpu_times:148 4         0.0     0.0
<string>.__new__:8                                                                                                                        220       0.0     0.0
C:\Python27\lib\socket.py.close:276                                                                                                       4         0.0     0.0
C:\Python27\lib\threading.py.__init__:558                                                                                                 1         0.0     0.0
<string>.__new__:8                                                                                                                        4         0.0     0.0
C:\Python27\lib\threading.py.notify:372                                                                                                   1         0.0     0.0
C:\Python27\lib\rfc822.py.getheader:285                                                                                                   4         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.handle_one_request:301                                                                                  1         0.0     0.0
C:\Python27\lib\xmlrpclib.py.end:816                                                                                                      3         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.do_POST:467                                                                                         1         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.is_rpc_path_valid:460                                                                               1         0.0     0.0
C:\Python27\lib\SocketServer.py.close_request:475                                                                                         1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\__init__.py.cpu_times:1066               4         0.0     0.0

对于短脚原本说,它可能不是颇有用,但有助于优化服务器类型的进程,尤为是考虑到能够随时间屡次调用printProfiler方法来分析和比较不一样的程序使用状况时,尤为如此。

相关文章
相关标签/搜索