Paddle模型性能分析工具Profiler定位瓶颈点优化程序详解

目录
  • Paddle模型性能分析Profiler
  • 1.使用Profiler工具调试程序性能
    • 1.1 使用cifar10数据集卷积神经网络进行图像分类
      • 1.1.1 获取性能调试前模型正常运行的ips
      • 1.1.2. 开启性能分析器,定位性能瓶颈点
      • 1.1.3. 优化程序,检查优化效果
      • 1.1.5 结果展示
  • 2 统计表单展示

Paddle模型性能分析Profiler

定位性能瓶颈点优化程序提升性能

Paddle Profiler是飞桨框架自带的低开销性能分析器,可以对模型运行过程的性能数据进行收集、统计和展示。性能分析器提供的数据可以帮助定位模型的瓶颈,识别造成程序运行时间过长或者GPU利用率低的原因,从而寻求优化方案来获得性能的提升

1.使用Profiler工具调试程序性能

在模型性能分析中,通常采用如下四个步骤:

  • 获取模型正常运行时的ips(iterations per second, 每秒的迭代次数),给出baseline数据。
  • 开启性能分析器,定位性能瓶颈点。
  • 优化程序,检查优化效果。
  • 获取优化后模型正常运行时的ips,和baseline比较,计算真实的提升幅度。

下面是使用神经网络对cifar10进行分类的示例代码,里面加上了启动性能分析的代码。通过这个比较简单的示例,来看性能分析工具是如何通过上述四个步骤在调试程序性能中发挥作用。

1.1 使用cifar10数据集卷积神经网络进行图像分类

import paddle
import paddle.nn.functional as F
from paddle.vision.transforms import ToTensor
import numpy as np
import matplotlib.pyplot as plt
print(paddle.__version__)

加载数据集

cifar10数据集由60000张大小为32 * 32的彩色 图片组成,其中有50000张图片组成了训练集,另外10000张图片组成了测试集。这些图片分为10个类别,将训练一个模型能够把图片进行正确的分类。

transform = ToTensor()
cifar10_train = paddle.vision.datasets.Cifar10(mode='train',
                                               transform=transform)
cifar10_test = paddle.vision.datasets.Cifar10(mode='test',
                                              transform=transform)

组建网络

接下来使用飞桨定义一个使用了三个二维卷积( Conv2D ) 且每次卷积之后使用 relu 激活函数,两个二维池化层( MaxPool2D ),和两个线性变换层组成的分类网络,来把一个(32, 32, 3)形状的图片通过卷积神经网络映射为10个输出,这对应着10个分类的类别

class MyNet(paddle.nn.Layer):
    def __init__(self, num_classes=1):
        super(MyNet, self).__init__()
        self.conv1 = paddle.nn.Conv2D(in_channels=3, out_channels=32, kernel_size=(3, 3))
        self.pool1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
        self.conv2 = paddle.nn.Conv2D(in_channels=32, out_channels=64, kernel_size=(3,3))
        self.pool2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
        self.conv3 = paddle.nn.Conv2D(in_channels=64, out_channels=64, kernel_size=(3,3))
        self.flatten = paddle.nn.Flatten()
        self.linear1 = paddle.nn.Linear(in_features=1024, out_features=64)
        self.linear2 = paddle.nn.Linear(in_features=64, out_features=num_classes)
    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = self.pool2(x)
        x = self.conv3(x)
        x = F.relu(x)
        x = self.flatten(x)
        x = self.linear1(x)
        x = F.relu(x)
        x = self.linear2(x)
        return x

模型训练&预测

接下来,用一个循环来进行模型的训练,将会:

使用 paddle.optimizer.Adam 优化器来进行优化。

使用 F.cross_entropy 来计算损失值。

使用 paddle.io.DataLoader 来加载数据并组建batch。

import paddle.profiler as profiler
#参数设置
epoch_num = 10
batch_size = 32
learning_rate = 0.001
val_acc_history = []
val_loss_history = []
def train(model):
    print('start training ... ')
    # turn into training mode
    model.train()
    opt = paddle.optimizer.Adam(learning_rate=learning_rate,
                                parameters=model.parameters())
    train_loader = paddle.io.DataLoader(cifar10_train,
                                        shuffle=True,
                                        batch_size=batch_size,
                                        num_workers=4)
    valid_loader = paddle.io.DataLoader(cifar10_test, batch_size=batch_size)
    # 创建性能分析器相关的代码
    def my_on_trace_ready(prof):# 定义回调函数,性能分析器结束采集数据时会被调用
        callback = profiler.export_chrome_tracing('./profiler_demo') # 创建导出性能数据到profiler_demo文件夹的回调函数
        callback(prof)  # 执行该导出函数
        prof.summary(sorted_by=profiler.SortedKeys.GPUTotal) # 打印表单,按GPUTotal排序表单项
    p = profiler.Profiler(scheduler = [3,14], on_trace_ready=my_on_trace_ready, timer_only=True) # 初始化Profiler对象
    p.start() # 性能分析器进入第0个step
    for epoch in range(epoch_num):
        for batch_id, data in enumerate(train_loader()):
            x_data = data[0]
            y_data = paddle.to_tensor(data[1])
            y_data = paddle.unsqueeze(y_data, 1)
            logits = model(x_data)
            loss = F.cross_entropy(logits, y_data)
            if batch_id % 1000 == 0:
                print("epoch: {}, batch_id: {}, loss is: {}".format(epoch, batch_id, loss.numpy()))
            loss.backward()
            opt.step()
            opt.clear_grad()
            p.step() # 指示性能分析器进入下一个step
            if batch_id == 19:
                p.stop() # 关闭性能分析器
                exit() # 做性能分析时,可以将程序提前退出
        # evaluate model after one epoch
        model.eval()
        accuracies = []
        losses = []
        for batch_id, data in enumerate(valid_loader()):
            x_data = data[0]
            y_data = paddle.to_tensor(data[1])
            y_data = paddle.unsqueeze(y_data, 1)
            logits = model(x_data)
            loss = F.cross_entropy(logits, y_data)
            acc = paddle.metric.accuracy(logits, y_data)
            accuracies.append(acc.numpy())
            losses.append(loss.numpy())
        avg_acc, avg_loss = np.mean(accuracies), np.mean(losses)
        print("[validation] accuracy/loss: {}/{}".format(avg_acc, avg_loss))
        val_acc_history.append(avg_acc)
        val_loss_history.append(avg_loss)
        model.train()
model = MyNet(num_classes=10)
train(model)
**部分结果展示:**
epoch: 6, batch_id: 0, loss is: [0.91811454]
epoch: 6, batch_id: 1000, loss is: [0.89851004]
[validation] accuracy/loss: 0.7232428193092346/0.8434960246086121
epoch: 7, batch_id: 0, loss is: [0.60690844]
epoch: 7, batch_id: 1000, loss is: [0.6912922]
[validation] accuracy/loss: 0.7049720287322998/0.887704074382782
epoch: 8, batch_id: 0, loss is: [0.6330824]
epoch: 8, batch_id: 1000, loss is: [0.5715592]
[validation] accuracy/loss: 0.7176517844200134/0.8511289954185486
epoch: 9, batch_id: 0, loss is: [0.29487646]
epoch: 9, batch_id: 1000, loss is: [0.9094696]
[validation] accuracy/loss: 0.7097643613815308/0.9166476130485535

1.1.1 获取性能调试前模型正常运行的ips

上述程序在创建Profiler时候,timer_only设置的值为True,此时将只开启benchmark功能,不开启性能分析器,程序输出模型正常运行时的benchmark信息如下

  • Reader Ratio:表示数据读取部分占训练batch迭代过程的时间占比,
  • reader_cost:代表数据读取时间,
  • batch_cost:代表batch迭代的时间,
  • ips:表示每秒能迭代多少次,即跑多少个batch。

可以看到,此时的ips为70.99,可将这个值作为优化对比的baseline。

 ============================================Perf Summary============================================
 Reader Ratio: 35.240%
 Time Unit: s, IPS Unit: steps/s
|                 |       avg       |       max       |       min       |
 |   reader_cost   |     0.00496     |     0.00542     |     0.00469     |
|    batch_cost   |     0.01408     |     0.01325     |     0.01246     |
 |       ips       |     70.99914    |     80.24470    |     75.46403    |

1.1.2. 开启性能分析器,定位性能瓶颈点

修改程序,将Profiler的timer_only参数设置为False, 此时代表不只开启benchmark功能,还将开启性能分析器,进行详细的性能分析。

p = profiler.Profiler(scheduler = [3,14], on_trace_ready=my_on_trace_ready, timer_only=False)

性能分析器会收集程序在第3到14次(不包括14)训练迭代过程中的性能数据,并在profiler_demo文件夹中输出一个json格式的文件,用于展示程序执行过程的timeline,可通过chrome浏览器的chrome://tracing 插件打开这个文件进行查看。

如图所示,把json文件load即可:

性能分析器还会直接在终端打印统计表单(建议重定向到文件中查看),查看程序输出的Model Summary表单

-----------------------------------------------Model Summary-----------------------------------------------
Time unit: ms
---------------  ------  ----------------------------------------  ----------------------------------------
Name             Calls   CPU Total / Avg / Max / Min / Ratio(%)    GPU Total / Avg / Max / Min / Ratio(%)
---------------  ------  ----------------------------------------  ----------------------------------------
ProfileStep      11      138.99 / 12.64 / 17.91 / 10.65 / 100.00   8.81 / 0.80 / 0.80 / 0.80 / 100.00
  Dataloader     11      16.88 / 1.53 / 6.91 / 0.09 / 12.14        0.00 / 0.00 / 0.00 / 0.00 / 0.00
  Forward        11      45.18 / 4.11 / 4.41 / 3.61 / 32.50        2.73 / 0.25 / 0.25 / 0.25 / 31.01
  Backward       11      27.63 / 2.51 / 2.85 / 2.37 / 19.88        4.04 / 0.37 / 0.37 / 0.36 / 45.81
  Optimization   11      19.75 / 1.80 / 1.89 / 1.61 / 14.21        1.05 / 0.10 / 0.10 / 0.09 / 11.56
  Others         -       29.55 / - / - / - / 21.26                 1.05 / - / - / - / 11.63
---------------  ------  ----------------------------------------  ----------------------------------------
Note:
在此表中,GPU 时间是该阶段调用的所有设备(GPU)事件的总和。
与概述摘要不同,如果两个设备(GPU)事件在不同的流上执行重叠时间,我们直接在这里求和。
  • 其中ProfileStep表示训练batch的迭代step过程,对应代码中每两次调用p.step()的间隔时间;
  • Dataloader表示数据读取的时间,即for batch_id, data in enumerate(train_loader())的执行时间;
  • Forward表示模型前向的时间,即logits = model(x_data)的执行时间,
  • Backward表示反向传播的时间,即loss.backward()的执行时间;
  • Optimization表示优化器的时间,即opt.step()的执行时间。

通过timeline可以看到,Dataloader占了执行过程的很大比重,Model Summary显示其接近了12%。分析程序发现,这是由于模型本身比较简单,需要的计算量小,再加上Dataloader 准备数据时只用了单进程来读取,使得程序读取数据时和执行计算时没有并行操作,导致Dataloader占比过大。

1.1.3. 优化程序,检查优化效果

识别到了问题产生的原因,对程序继续做如下修改,将Dataloader的num_workers设置为4,使得能有多个进程并行读取数据。

train_loader = paddle.io.DataLoader(cifar10_train,
                                    shuffle=True,
                                    batch_size=batch_size,
                                    num_workers=4)

重新对程序进行性能分析,新的timeline和Model Summary如下所示

-----------------------------------------------Model Summary-----------------------------------------------
Time unit: ms
---------------  ------  ----------------------------------------  ----------------------------------------
Name             Calls   CPU Total / Avg / Max / Min / Ratio(%)    GPU Total / Avg / Max / Min / Ratio(%)
---------------  ------  ----------------------------------------  ----------------------------------------
ProfileStep      11      89.44 / 8.13 / 8.76 / 7.82 / 100.00       8.82 / 0.80 / 0.80 / 0.80 / 100.00
  Dataloader     11      1.51 / 0.14 / 0.16 / 0.12 / 1.69          0.00 / 0.00 / 0.00 / 0.00 / 0.00
  Forward        11      31.67 / 2.88 / 3.17 / 2.82 / 35.41        2.72 / 0.25 / 0.25 / 0.24 / 36.11
  Backward       11      25.35 / 2.30 / 2.49 / 2.20 / 28.34        4.07 / 0.37 / 0.37 / 0.37 / 42.52
  Optimization   11      11.67 / 1.06 / 1.16 / 1.01 / 13.04        1.04 / 0.09 / 0.10 / 0.09 / 10.59
  Others         -       19.25 / - / - / - / 21.52                 1.06 / - / - / - / 10.78
---------------  ------  ----------------------------------------  ----------------------------------------

可以看到,从Dataloader中取数据的时间大大减少,从12%变成了平均只占一个step的1.69%,并且平均一个step所需要的时间也相应减少了从1.53到0.14。

### 1.1.4 获取优化后模型正常运行的ips,确定真实提升幅度
重新将timer_only设置的值为True,获取优化后模型正常运行时的benchmark信息
============================================Perf Summary============================================
Reader Ratio: 1.718%
Time Unit: s, IPS Unit: steps/s
|                 |       avg       |       max       |       min       |
|   reader_cost   |     0.00013     |     0.00015     |     0.00012     |
|    batch_cost   |     0.00728     |     0.00690     |     0.00633     |
|       ips       |    137.30879    |    158.01126    |    144.91796    |

此时从原来的Reader Ratio: 35.240%---->Reader Ratio: 1.718%

ips的值变成了137.3,相比优化前的baseline70.99,模型真实性能提升了193%。

注意点:

由于Profiler开启的时候,收集性能数据本身也会造成程序性能的开销,因此正常跑程序时请不要开启性能分析器,性能分析器只作为调试程序性能时使用。

  • 1.如果想获得程序正常运行时候的 benchmark信息(如ips),可以像示例一样将Profiler的timer_only参数设置为True,此时不会进行详尽的性能数据收集,几乎不影响程序正常运行的性能,所获得的benchmark信息也趋于真实。
  • 2.benchmark信息计算的数据范围是从调用Profiler的start方法开始,到调用stop方法结束这个过程的数据。而Timeline和性能数据的统计表单的数据范围是所指定的采集区间,如这个例子中的第3到14次迭代,这会导致开启性能分析器时统计表单和benchmark信息输出的值不同(如统计到的Dataloader的时间占比)。
  • 3.当benchmark统计的范围和性能分析器统计的范围不同时, 由于benchmark统计的是平均时间,如果benchmark统计的范围覆盖了性能分析器开启的范围,也覆盖了关闭性能调试时的正常执行的范围,此时benchmark的值没有意义,因此开启性能分析器时请以性能分析器输出的统计表单为参考,这也是为何上面示例里在开启性能分析器时没贴benchmark信息的原因。

1.1.5 结果展示

#结果展示
plt.plot(val_acc_history, label = 'validation accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 0.8])
plt.legend(loc='lower right')

2 统计表单展示

统计表单负责对采集到的数据(Event)从多个不同的角度进行解读,也可以理解为对timeline进行一些量化的指标计算。 目前提供Device Summary、Overview Summary、Model Summary、Distributed Summary、Operator Summary、Kernel Summary、Memory Manipulation Summary和UserDefined Summary的统计表单,每个表单从不同的角度进行统计计算。每个表单的统计内容简要叙述如下:

Device Summary

-------------------Device Summary-------------------
------------------------------  --------------------
Device                          Utilization (%)
------------------------------  --------------------
CPU(Process)                    77.13
CPU(System)                     25.99
GPU2                            55.50
------------------------------  --------------------
Note:
CPU(进程) 利用率 = 当前进程在所有 cpu 内核上的 CPU 时间/经过的时间,因此最大利用率可以达到 100% * cpu 内核数。
CPU(系统)利用率=所有进程在所有cpu内核上的CPU时间(忙碌时间)/(忙碌时间+空闲时间)。
GPU 利用率 = 当前进程 GPU 时间 / 已用时间。
----------------------------------------------------

DeviceSummary提供CPU和GPU的平均利用率信息。其中

CPU(Process): 指的是进程的cpu平均利用率,算的是从Profiler开始记录数据到结束这一段过程,进程所利用到的 cpu core的总时间与该段时间的占比。因此如果是多核的情况,对于进程来说cpu平均利用率是有可能超过100%的,因为同时用到的多个core的时间进行了累加。

CPU(System): 指的是整个系统的cpu平均利用率,算的是从Profiler开始记录数据到结束这一段过程,整个系统所有进程利用到的cpu core总时间与该段时间乘以cpu core的数量的占比。可以当成是从cpu的视角来算的利用率。

GPU: 指的是进程的gpu平均利用率,算的是从Profiler开始记录数据到结束这一段过程,进程在gpu上所调用的kernel的执行时间 与 该段时间 的占比。

Overview Summary

Overview Summary用于展示每种类型的Event一共分别消耗了多少时间,对于多线程或多stream下,如果同一类型的Event有重叠的时间段,采取取并集操作,不对重叠的时间进行重复计算。

---------------------------------------------Overview Summary---------------------------------------------
Time unit: ms
-------------------------  -------------------------  -------------------------  -------------------------
Event Type                 Calls                      CPU Time                   Ratio (%)
-------------------------  -------------------------  -------------------------  -------------------------
ProfileStep                8                          4945.15                    100.00
  CudaRuntime              28336                      2435.63                    49.25
  UserDefined              486                        2280.54                    46.12
  Dataloader               8                          1819.15                    36.79
  Forward                  8                          1282.64                    25.94
  Operator                 8056                       1244.41                    25.16
  OperatorInner            21880                      374.18                     7.57
  Backward                 8                          160.43                     3.24
  Optimization             8                          102.34                     2.07
-------------------------  -------------------------  -------------------------  -------------------------
                          Calls                      GPU Time                   Ratio (%)
-------------------------  -------------------------  -------------------------  -------------------------
  Kernel                   13688                      2744.61                    55.50
  Memcpy                   496                        29.82                      0.60
  Memset                   104                        0.12                       0.00
  Communication            784                        257.23                     5.20
-------------------------  -------------------------  -------------------------  -------------------------
Note:
在此表中,我们根据事件类型汇总了所有收集到的事件。
在主机上收集的事件时间显示为 CPU 时间,如果在设备上则显示为 GPU 时间。
不同类型的事件可能会重叠或包含,例如 Operator 包括 OperatorInner,因此比率之和不是 100%。
有重叠的同类型事件的时间不会计算两次,合并后所有时间相加。
Example:
Thread 1:
  Operator: |___________|     |__________|
Thread 2:
  Operator:   |____________|     |___|
After merged:
  Result:   |______________|  |__________|
----------------------------------------------------------------------------------------------------------

不在继续详细说明,参考项目即可:

项目链接,fork一下即可使用
aistudio.baidu.com/aistudio/pr…

以上就是Paddle模型性能分析工具Profiler定位瓶颈点优化程序详解的详细内容,更多关于Paddle分析工具Profiler的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python PaddleNLP信息抽取提取快递单信息

    目录 5 条标注数据,搞定物流快递单信息抽取 智能立体库盘点 近几年,制造业作为国民经济主体,是国家创造力.竞争力和综合国力的重要体现.作为制造强国建设的主攻方向,可以说,智能制造发展水平关乎我国未来制造业的全球地位. 制造业与物流结合紧密,随着制造业的高速发展,对自动化率.全产业链协同和生产效率再提高等方向均提出了更高的要求,需要物流仓储能够匹配相应的生产节奏. 同时,据统计,我国制造业生产成本中,物流占比高达三成,降低物流成本成为了制造业利润提升的关键一环. 今天,我将基于智能制造 - 精益

  • Python利用PaddleOCR制作个搜题小工具

    目录 介绍 安装 安装PaddlePaddle飞桨框架 安装PaddleOCR 代码使用 搜题小工具 安装ADB 截图并保存题目区域图片 OCR识别,获取题目 打开浏览器搜索 完整代码 介绍 PaddleOCR 是一个基于百度飞桨的OCR工具库,包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别.竖排文本识别.长文本识别.同时支持多种文本检测.文本识别的训练算法. 本教程将介绍PaddleOCR的基本使用方法以及如何使用它开发一个自动搜题的小工具. 项目地址 OR 安装 虽然

  • Python PaddleNLP实现自动生成虎年藏头诗

    目录 一. 数据处理 1.paddlenlp升级 2.提取诗头 3.生成词表 4.定义dataset 二.定义模型并训练 1.模型定义 2.模型训练 3.模型保存 三.生成藏头诗 总结 一. 数据处理 本项目中利用古诗数据集作为训练集,编码器接收古诗的每个字的开头,解码器利用编码器的信息生成所有的诗句.为了诗句之间的连贯性,编码器同时也在诗头之前加上之前诗句的信息.举例: “白日依山尽,黄河入海流,欲穷千里目,更上一层楼.” 可以生成两个样本: 样本一:编码器输入,“白”:解码器输入,“白日依山

  • PaddleOCR 识别表情包文字示例详解

    目录 引言 安装 PaddleOCR 本地处理 在 flask 中处理 引言 最近在做个表情包的小程序,涉及到表情包搜索功能.我们上传表情包的时候,只有一张图,怎么搜索?这个时候我们想到就是将表情包的文字提取出来,作为搜索的内容.那么这就需要用到 ocr 技术了. 经过几个 ocr 的库的使用,小编强烈推荐使用 PaddleOCR,一款文本识别效果不输于商用的Python库! 对于 PaddleOCR 本文不会过多介绍,可自行搜索.重点是如何使用 PaddleOCR 解决我的问题. 安装 Pad

  • python PaddleSpeech实现婴儿啼哭识别

    目录 一.基于PaddleSpeech的婴儿啼哭识别 1.项目背景 2.数据说明: 二.PaddleSpeech环境准备 三.数据预处理 1.数据解压缩 2.查看声音文件 3.音频文件长度处理 3.自定义数据集 四.模型训练 1.选取预训练模型 2.构建分类模型 3.finetune 五.模型训练 六.注意事项 一.基于PaddleSpeech的婴儿啼哭识别 1.项目背景 对婴儿来说,啼哭声是一种通讯的方式,一个非常有限的,但类似成年人进行交流的方式.它也是一种生物报警器,向外界传达着婴儿生理和

  • PaddleNLP ppdiffusers 自动生成兔了个兔海报

    目录 欢欢喜喜辞旧岁 下载PaddleNLP 安装PaddleNLP 重启notebook 安装ppdiffusers diffusion文图生成 选定diffusion模型 图片生成 海报合成 查看海报 欢欢喜喜辞旧岁 辞旧迎新之际,来 AI Studio 一起 #欢喜迎兔年# !分享不同新年风俗,共享一段快乐时光! p>下面就开始我们的海报之旅 下载PaddleNLP from IPython.display import clear_output %cd ~ !git clone -b d

  • Paddle模型性能分析工具Profiler定位瓶颈点优化程序详解

    目录 Paddle模型性能分析Profiler 1.使用Profiler工具调试程序性能 1.1 使用cifar10数据集卷积神经网络进行图像分类 1.1.1 获取性能调试前模型正常运行的ips 1.1.2. 开启性能分析器,定位性能瓶颈点 1.1.3. 优化程序,检查优化效果 1.1.5 结果展示 2 统计表单展示 Paddle模型性能分析Profiler 定位性能瓶颈点优化程序提升性能 Paddle Profiler是飞桨框架自带的低开销性能分析器,可以对模型运行过程的性能数据进行收集.统计

  • .NET Visual Studio 代码性能分析工具

    下面通过图文并茂的方式给大家介绍下,具体内容如下: 软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和性能测试,从而大大简化程序员进行代码性能优化的过程.MSDN杂志2011年7月份曾发布主题为".NET代码分析工具和技术"的那一期,让广大程序员收获颇丰.四年过去之后,这些工具又进一步做出了很多改进,同时也出现了更多的选择.本文对当前主流

  • .NET  Visual Studio 代码性能分析工具

    下面通过图文并茂的方式给大家介绍下,具体内容如下: 软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和性能测试,从而大大简化程序员进行代码性能优化的过程.MSDN杂志2011年7月份曾发布主题为".NET代码分析工具和技术"的那一期,让广大程序员收获颇丰.四年过去之后,这些工具又进一步做出了很多改进,同时也出现了更多的选择.本文对当前主流

  • PHP调试及性能分析工具Xdebug详解

    程序开发过程中,一般用得最多的调试方法就是用echo.print_r().var_dump().printf()等将语句打印出来.对PHP脚本的执行效率,通常是脚本执行时间.对数据库SQL的效率,通常是数据库Query时间,但这样并不能真正定位和分析脚本执行和数据库查询的瓶颈所在?对此,有一个叫Xdebug(www.xdebug.org)的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况. 一.以windows平台对此模块的安装做简单的介绍: 1. 下载PH

  • Python性能分析工具Profile使用实例

    这篇文章主要介绍了Python性能分析工具Profile使用实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 profile,cProfile 与 hotshot 等.其中 Profiler 是 python 自带的一组程序,能够描述程序运行时候的性能,并提供各种统计帮助用户定位程序

  • Python性能分析工具py-spy原理用法解析

    Py-Spy介绍 引用官方的介绍: Py-Spy是Python程序的抽样分析器. 它允许您可视化查看Python程序在哪些地方花了更多时间,整个监控方式无需重新启动程序或以任何方式修改工程代码. Py-Spy的开销非常低:它是用Rust编写的,速度与编译的Python程序不在同一个进程中运行. 这意味着Py-Spy可以安全地用于生成生产环境中的Python应用调优分析. github:https://github.com/benfred/py-spy 安装 pip install py-spy

  • Python性能分析工具pyinstrument提高代码效率

    目录 安装 简单的使用 分析 Flask 代码 分析 Django 代码 分析异步代码 工作原理 最后的话 天下武功,唯快不破. 编程也不例外,你的代码跑的快,你能快速找出代码慢的原因,你的码功就高. 安装 pip install pyinstrument 简单的使用 在程序的开始,启动 pyinstrument 的 Profiler,结束时关闭 Profiler 并打印分析结果如下: from pyinstrument import Profiler profiler = Profiler()

  • Java CPU性能分析工具代码实例

    这篇文章主要介绍了Java CPU性能分析工具代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 背景 有处理过生产问题的同学基本都能遇到系统忽然缓慢,CPU突然飙升,甚至整个应用请求不可用.当出现这种情况下,在不影响数据准确性的前提下,我们应该尽快导出jstack和内存信息,然后重启系统,尽快回复系统的可用性,避免用户体验过差.本文针对CPU飙升问题,提供该问题的排查思路,从而能够快速定位到某线程甚至某快代码导致CPU飙升,从而提供处理该

  • PHP7下安装并使用xhprof性能分析工具

    该 xhprof 版本是从 https://github.com/longxinH/xhprof 获取 安装 xhprof cd xhprof/extension/ phpize ./configure  make 然后在/etc/php.ini中根据情况加入 extension=xhprof.so 执行 php -m | grep xhprof 可以看见输出,说明php扩展安装成功,然后重启Apache或者php-fpm 运行 可以直接运行从github上clone下来的文件里面example

  • Go 库性能分析工具pprof

    目录 场景 pprof 生成 profile 文件 CPU 性能分析 内存性能分析 分析 profile 文件 && 优化代码 go tool pprof top 命令 list 命令 总结 场景 我们一般没必要过度优化 Go 程序性能.但是真正需要时,Go 提供的 pprof 工具能帮我们快速定位到问题.比如,我们团队之前有一个服务,在本地和测试环境没问题,一到灰度环境,就报 cpu 负载过高,后经排查,发现某处代码死循环了.我把代码简化成如下: // 处理某些业务,真实的代码中这个死循

随机推荐