我正在编写一个界面来帮助我分析python脚本。 我借用代码从profile.py源代码执行python脚本。 我意识到,当我连续两次分析相同的代码时,它会第二次返回不同数量的函数调用。 例如,在myscript.py上执行以下代码:

from cProfile import Profile
import sys
import os.path

for i in range(3):
    prof = Profile()

    progname = 'myscript.py'
    sys.path.insert(0, os.path.dirname(progname))
    with open(progname, 'rb') as fp:
        code = compile(fp.read(), progname, 'exec')
    globs = {
            '__file__': progname,
            '__name__': '__main__',
            '__package__': None,
            '__cached__': None,
            }
    prof.runctx(code, globs, None)
    prof.create_stats()
    print(len(prof.stats))

给我

511
30
30

作为输出。 为什么第二次调用函数的数量会变小? 哪个号码是正确的号码? 我能做什么才能得到同样的结果?


myscript.py看起来像:

import numpy
import numpy.linalg

if __name__ == '__main__':

    r = numpy.random.rand(1000, 1000)
    numpy.linalg.inv(r)

===============>>#1 票数:1 已采纳

似乎函数调用计数不同的原因是因为第二次运行代码时myscript.py导入的模块不会再次导入。

获得一致结果的第一种方法是在执行分析之前导入myscript.py 但是,这意味着如果我导入的模块在导入时执行某些任务,则不会对其进行分析。

prof = Profile()

progname = 'myscript.py'
sys.path.insert(0, os.path.dirname(progname))
modname, _ = os.path.splitext(os.path.basename(progname))
__import__(modname, globals(), locals(), [], 0)
with open(progname, 'rb') as fp:
    code = compile(fp.read(), progname, 'exec')
globs = {
        '__file__': progname,
        '__name__': '__main__',
        '__package__': None,
        '__cached__': None,
        }
prof.runctx(code, globs, None)
prof.create_stats()
print(len(prof.stats))

我找到的第二种方法是删除执行脚本时注册的所有模块。 优点是,如果我在GUI运行时修改源,它将重新加载更改。 我现在的缺点是,一些atexit注册处理程序现在崩溃,因为之前删除了所需的模块:

prof = Profile()

progname = 'myscript.py'
sys.path.insert(0, os.path.dirname(progname))
with open(progname, 'rb') as fp:
    code = compile(fp.read(), progname, 'exec')
globs = {
        '__file__': progname,
        '__name__': '__main__',
        '__package__': None,
        '__cached__': None,
        }
modules = sys.modules.copy()
prof.runctx(code, globs, None)
newmodes = [modname for modname in sys.modules if modname not in modules]
for modname in newmodes:
    del sys.modules[modname]
prof.create_stats()
print(len(prof.stats))

最后,我找到的最好方法是在一个单独的进程中执行分析:

import concurrent.futures
import marshal
from cProfile import Profile
from pstats import Stats
import sys

progname = 'myscript.py'
with concurrent.futures.ProcessPoolExecutor() as executor:
    future = executor.submit(_run, progname)
    stats = Stats()
    stats.stats = marshal.loads(future.result())
    stats.get_top_level_stats()

def _run(progname):
    sys.path.insert(0, os.path.dirname(progname))

    with open(progname, 'rb') as fp:
        code = compile(fp.read(), progname, 'exec')
    globs = {
        '__file__': progname,
        '__name__': '__main__',
        '__package__': None,
    }
    prof = Profile()
    prof.runctx(code, globs, None)
    prof.create_stats()
    return marshal.dumps(prof.stats)

  ask by Charles Brunet translate from so

未解决问题?本站智能推荐:

1回复

Python分析-代码之外的汇总函数调用

我正在尝试分析django单元测试(如果测试速度更快,我们将更频繁地运行它们)。 我已经通过python内置的cProfile Profiler运行了它,生成了一个pstats文件。 但是,信噪比很差。 列出的功能太多。 当我进行一个数据库查询时,将调用很多django内部函数。
1回复

.profile中的Bash函数未运行SimpleHTTPServer-找不到文件

所以我有一个简单的bash函数存储在〜/ .profile中,如下所示: function testingServer() { local port="${1:-8000}" python SimpleHTTPServer "$port" open "http://localhost:${p
1回复

调用自定义探查器时在python中抛出奇怪的异常

我写了一个探查器演示,如下所示: 然后我就这样出来了: 这让我很困惑。 此问题是由inspect.isfunction引起的。 我试过在_profile函数中使用许多其他模块,它们都有相同的错误: 如果我不使用_profiler任何模块,则程序运行正常。 为什么
1回复

Django,使用没有调用模型的库User检索用户配置文件

我尝试显示基于PK的用户个人资料。 因此,我创建了一个名为“个人资料”的菜单。 用户单击菜单后,用户可以查看配置文件。 我尝试了这个: 还有这个: 在base.html中: 在模板中,profile.html: urls.py 该配置文件从未显
1回复

Python分析:在每行函数上花费的时间

我一直在研究配置文件中的示例,我在运行时已经进入了工作流程 这给了我一些关于调用次数等的一般统计数据。 请注意,这是相当神秘的:我在myFunc使用numpy (比如numpy.sum , *等),但我无法在stats对象中找到这些调用。 我想看到的是在函数myFunc的源代码的每一
1回复

python:如何跟踪大型项目中的函数执行顺序

我想跟踪scrapy框架中的函数/类执行顺序。 默认项目中有多个* .py文件,我想知道哪个py文件和类已按顺序执行。 将记录器线放在每个类和功能中听起来很愚蠢。 如何可视化此订单? cprofile主要用于测量总时间。 我还可以将一个模块内的执行顺序可视化,这是常见问题,但是可视
4回复

如何获取特定运行的方法/函数调用跟踪?

给定一个Java或JavaScript程序,执行后,打印出一系列调用。 调用按调用顺序进行。 例如 那么呼叫跟踪应该是: 是否有任何工具可以剖析和输出此类信息? 看来这是调试或性能调整的常见需求。 我注意到有些分析器可以执行此操作,但是我更喜欢一个更简单/易于使用的分
1回复

分析C ++析构函数调用

我正在使用intel composer xe 2013的intel c ++编译器对在优化级别-O3上编译的C ++应用程序进行性能分析。探查器(OS X上的Instruments)指出,花了很大一部分时间来调用特定类型的Destructor。宾语。 但是,它不会为我提供有关首先使用什么功能分
2回复

检查数据库调用次数

关于性能调优,我想找出每个页面正在进行的数据库调用。 此外,执行的存储过程和查询。 我正在使用Asp.net和SQL Server 2008.在某些地方,我们直接在调用SP的C#insead中编写了查询。 我尝试使用SQL Profiler。 在那里,如果我选择SP,我可以跟踪SP调
1回复

python循环第二次不调用函数

下面的代码给出了视频中“面部”的姿势估计。 我修改了代码以将文件夹/目录作为输入,并期望它处理目录中的所有视频。 使用下面的代码我希望处理文件夹中的所有视频,但'for'循环只处理一个视频而不处理其他视频,下面是循环,它只调用一次parse_video。 文件夹(videoFolde