编写MindSpore数据集加载代码的时候,有时候会遇到一些蛊惑的代码行为,比方不晓得代码卡在哪里不动了,仿佛解决的很慢,或者写了死循环的逻辑。这些问题往往会破费很多精力打点去调试python代码,那么有没有不便的工具帮咱们这么做呢—— 有请明天的配角:py-spypy-spy 介绍援用官网的话:py-spy是Python程序的采样分析器。它能够让您可视化Python程序破费的工夫在什么上,而无需重新启动程序或以任何形式批改代码。py-spy开销极低:它是用Rust编写的,以进步速度,并且与剖析的Python程序不在雷同的过程中运行。这意味着py-spy能够平安地用于生产Python代码。官网github地址:https://github.com/benfred/py...如果有相干的问题也能够去github发问。py-spy 装置pip install py-spy装置后应用 py-spy -h能够验证装置,并查看应用帮忙。py-spy -hpy-spy 0.3.12
Sampling profiler for Python programs

USAGE:

py-spy <SUBCOMMAND>

OPTIONS:

-h, --help       Print help information-V, --version    Print version information

SUBCOMMANDS:

record    Records stack trace information to a flamegraph, speedscope or raw filetop       Displays a top like view of functions consuming CPUdump      Dumps stack traces for a target program to stdouthelp      Print this message or the help of the given subcommand(s)

py-spy 基本功能个别在命令行中运行py-spy,并对py-spy传入要剖析的过程的PID或要运行的python程序。py-spy具备三个子命令record,top和dump:record生成火焰图

top实时查看每个函数运行工夫并统计

dump显示每个python线程的以后调用堆栈

应用py-spy调试MindSpore数据集加载结构一个数据迭代很慢的场景先上一个经典代码test_dataset.pyimport mindspore.dataset as ds
import numpy as np
import time
class DatasetGenerator:

def __init__(self):    passdef __getitem__(self, item):    self.do_something()    return (np.array([item]),)def do_something(self):    cnt = 0    for i in range(100000000):        cnt += 1def __len__(self):    return 50

def test_generator_0():

data1 = ds.GeneratorDataset(DatasetGenerator(), ["data"])start = time.time()for item in data1.create_dict_iterator(num_epochs=1, output_numpy=True):    print("data time:", time.time() - start)    start = time.time()

尽管这个用例比较简单,然而的确会看到迭代的时候出数据很慢,运行一下能够看到data time: 5.431891679763794
data time: 5.6114866733551025
data time: 5.38549542427063
data time: 5.577831268310547
基本上5秒才读出一条数据,50条数据就是250秒!这才50条数据,如果10w条呢,这个读取工夫难以承受。那么到底问题呈现在哪里呢?(尽管明眼能看到do_something这个函数有点问题,然而咱们当初伪装不晓得)咱们须要py-spy帮咱们定位一下问题。应用py-spy的top性能查看调用栈和工夫占比咱们从新运行一下这个脚本python test_dataset.py &留神咱们容许的时候加了 & 使其能够在后盾运行,同时返回一个pid,比方这样

咱们失去了这个python的过程id 116079,有了这个pid之后,咱们就能够利用py-spy给咱们做实时剖析了,接下来咱们在命令行中输出py-spy top --pid 116079如果遇到这个提醒Permission Denied: Try running again with elevated permissions by going 'sudo env "PATH=$PATH" !!'
从新在命令行输出这个即可sudo env “PATH=$PATH” !!此时将会看到py-spy列出了调用栈及相干的函数用时占比:

直观地从这个调用栈剖析,do_something这个函数竟然占用了100%的运行工夫,运行超过了50+s,必定有某些问题!或是解决逻辑太慢,或是写了死循环?那么咱们就能够疾速来到代码的这里看看产生什么事了def do_something(self):

cnt = 0for i in range(100000000):    cnt += 1

天哪!这里竟然有一个一亿次的循环加法,到底是谁写的代码!(不是我)咱们能够通过优化这一部分代码,来晋升整体数据处理的速度。总的来说py-spy是一个挺不便的工具,帮忙用户疾速定位python的性能问题,除了top性能之外,py-spy也提供了dump性能把残缺的堆栈写入到本地不便剖析。当咱们在 debug 一个线上正在运行的程序的时候,只须要提供过程id,py-spy就能够间接接入应用。