<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>性能分析 &#8211; 编码无悔 /  Intent &amp; Focused</title>
	<atom:link href="https://www.codelast.com/tag/%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codelast.com</link>
	<description>最优化之路</description>
	<lastBuildDate>Mon, 27 Apr 2020 17:39:30 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>[原创] 如何查看一个Python进程在&quot;干什么&quot;： py-spy 来帮忙</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%a6%82%e4%bd%95%e6%9f%a5%e7%9c%8b%e4%b8%80%e4%b8%aapython%e8%bf%9b%e7%a8%8b%e5%9c%a8%e5%b9%b2%e4%bb%80%e4%b9%88%ef%bc%9a-py-spy-%e6%9d%a5%e5%b8%ae%e5%bf%99/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%a6%82%e4%bd%95%e6%9f%a5%e7%9c%8b%e4%b8%80%e4%b8%aapython%e8%bf%9b%e7%a8%8b%e5%9c%a8%e5%b9%b2%e4%bb%80%e4%b9%88%ef%bc%9a-py-spy-%e6%9d%a5%e5%b8%ae%e5%bf%99/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Tue, 12 Nov 2019 12:45:41 +0000</pubDate>
				<category><![CDATA[原创]]></category>
		<category><![CDATA[综合]]></category>
		<category><![CDATA[py-spy]]></category>
		<category><![CDATA[Python进程]]></category>
		<category><![CDATA[干什么]]></category>
		<category><![CDATA[性能分析]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=10802</guid>

					<description><![CDATA[<p>
如果你觉得一个运行中的Python程序有问题，例如它的耗时比你预想的要长很多，那么你可能会想知道它到底在&#8220;干什么&#8221;，有很多方法可以实现这个目的，但是很多都是需要修改Python代码来配合的，这显然是让人最不爽的方式。<br />
而&#160;<a href="https://github.com/benfred/py-spy" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">py-spy</span></a>&#160;这个工具提供了一种<span style="color:#0000ff;">无侵入</span>的方式来达成这个目的：</p>
<blockquote>
<p>
		py-spy是Python程序的采样分析器。 它使你可以直观地看到Python程序花费的时间，而无需重新启动程序或以任何方式修改代码。 py-spy的开销非常低：为了提高速度，它是用Rust编写的，并且它与被分析的Python程序不在同一进程中运行。 这意味着py-spy可以安全地用于生产环境的Python代码。</p>
</blockquote>
<p><span id="more-10802"></span><br />
py-spy 的工作原理：在Linux上使用process_vm_readv系统调用，在OSX上使用vm_read，在Windows上使用ReadProcessMemory来直接读取Python程序的内存。</p>
<p>下面就来看看怎么把 py-spy 用起来。<br />
<span style="color:#b22222;">环境：Ubuntu 16.04 LTS，Python 3.6.9</span></p>
<p><span style="color:#ff0000;"><span style="background-color:#00ff00;">▶</span></span> 安装 py-spy<br />
最简单的方法是用 pip 安装：</p>
<blockquote>
<p>
		pip install py-spy</p>
</blockquote>
<p>但对我来说，我是在Anaconda环境下使用Python，所以我不想这样干。Anaconda cloud上面没有Linux版的 py-spy，于是我最省力的办法，就是用Rust的包管理工具 Cargo 来安装 py-spy 了。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
首先安装Rust：</p>
<blockquote>
<p>
		curl https://sh.rustup.rs -sSf &#124; bash</p>
</blockquote>
<p>这样 Rust 就被安装到了当前用户的 .cargo&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%a6%82%e4%bd%95%e6%9f%a5%e7%9c%8b%e4%b8%80%e4%b8%aapython%e8%bf%9b%e7%a8%8b%e5%9c%a8%e5%b9%b2%e4%bb%80%e4%b9%88%ef%bc%9a-py-spy-%e6%9d%a5%e5%b8%ae%e5%bf%99/" class="read-more">Read More </a></p>]]></description>
										<content:encoded><![CDATA[<p>
如果你觉得一个运行中的Python程序有问题，例如它的耗时比你预想的要长很多，那么你可能会想知道它到底在&ldquo;干什么&rdquo;，有很多方法可以实现这个目的，但是很多都是需要修改Python代码来配合的，这显然是让人最不爽的方式。<br />
而&nbsp;<a href="https://github.com/benfred/py-spy" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">py-spy</span></a>&nbsp;这个工具提供了一种<span style="color:#0000ff;">无侵入</span>的方式来达成这个目的：</p>
<blockquote>
<p>
		py-spy是Python程序的采样分析器。 它使你可以直观地看到Python程序花费的时间，而无需重新启动程序或以任何方式修改代码。 py-spy的开销非常低：为了提高速度，它是用Rust编写的，并且它与被分析的Python程序不在同一进程中运行。 这意味着py-spy可以安全地用于生产环境的Python代码。</p>
</blockquote>
<p><span id="more-10802"></span><br />
py-spy 的工作原理：在Linux上使用process_vm_readv系统调用，在OSX上使用vm_read，在Windows上使用ReadProcessMemory来直接读取Python程序的内存。</p>
<p>下面就来看看怎么把 py-spy 用起来。<br />
<span style="color:#b22222;">环境：Ubuntu 16.04 LTS，Python 3.6.9</span></p>
<p><span style="color:#ff0000;"><span style="background-color:#00ff00;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span> 安装 py-spy<br />
最简单的方法是用 pip 安装：</p>
<blockquote>
<p>
		pip install py-spy</p>
</blockquote>
<p>但对我来说，我是在Anaconda环境下使用Python，所以我不想这样干。Anaconda cloud上面没有Linux版的 py-spy，于是我最省力的办法，就是用Rust的包管理工具 Cargo 来安装 py-spy 了。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
首先安装Rust：</p>
<blockquote>
<p>
		curl https://sh.rustup.rs -sSf | bash</p>
</blockquote>
<p>这样 Rust 就被安装到了当前用户的 .cargo 目录下。<br />
再修改 .bashrc，把Cargo添加到PATH中：</p>
<blockquote>
<p>
		export RUST_HOME=/home/codelast/.cargo<br />
		export PATH=$RUST_HOME/bin:$PATH</p>
</blockquote>
<p>现在事情就变得无比简单了，安装 py-spy：</p>
<blockquote>
<p>
		cargo install py-spy</p>
</blockquote>
<p>如果执行这个命令出错，提示：</p>
<blockquote>
<div>
		error: linking with `cc` failed: exit code: 1</div>
<div>
		&nbsp; |</div>
<div>
		&nbsp; (...中间省略...)</div>
<div>
		&nbsp; = note: /usr/bin/ld: cannot find -lunwind</div>
<div>
		&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /usr/bin/ld: cannot find -lunwind-ptrace</div>
<div>
		&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /usr/bin/ld: cannot find -lunwind-x86_64</div>
<div>
		&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collect2: error: ld returned 1 exit status</div>
<div>
		&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div>
<div>
		&nbsp;</div>
<div>
		error: aborting due to previous error</div>
<div>
		&nbsp;</div>
<div>
		error: failed to compile `py-spy v0.3.0`, intermediate artifacts can be found at `/tmp/cargo-installZWBhFq`</div>
<div>
		&nbsp;</div>
<div>
		Caused by:</div>
<div>
		&nbsp; could not compile `py-spy`.</div>
</blockquote>
<div>
	那么你可以尝试先安装这个package再重试：</div>
<blockquote>
<div>
		sudo apt install libunwind-dev</div>
</blockquote>
<div>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0); background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span>&nbsp;使用 py-spy<br />
	首先启动一个Python程序，用 ps -ef 找到它的 pid，然后就可以用 py-spy 来&ldquo;监控&rdquo;它了：</div>
<blockquote>
<div>
		py-spy top --pid 1780</div>
</blockquote>
<div>
	这里 1780 是我的Python进程 pid。不出意外的话，马上会报错：</div>
<blockquote>
<div>
		Permission Denied: Try running again with elevated permissions by going &#39;sudo env &quot;PATH=$PATH&quot; !!&#39;</div>
</blockquote>
<div>
	按照上面的提示，执行以下命令并输入sudo的密码：</div>
<blockquote>
<div>
		sudo env &quot;PATH=$PATH&quot; !!</div>
</blockquote>
<div>
	注意：<span style="color:#0000ff;">那两个感叹号也是命令的一部分</span>，不要觉得奇怪。<br />
	现在你会看到类似于 Linux top 命令的输出：<br />
	<a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><img decoding="async" alt="py-spy top" src="https://www.codelast.com/wp-content/uploads/2019/11/py-spy_top_pid.png" style="width: 700px; height: 377px;" /></a><br />
	你可以从中找到每个函数的执行时间。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	或者你想要酷炫一点的结果，可以生成火焰图：</div>
<blockquote>
<div>
		py-spy record -o profile.svg --pid 1780</div>
</blockquote>
<div>
	这里也会像上面一样提示没权限，同理，按提示执行上面同样的 sudo 命令，再等待一定的时间之后 Ctrl+C 中断掉，就会生成一张图片 profile.svg：<br />
	<a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><img decoding="async" alt="py-spy record profile" src="https://www.codelast.com/wp-content/uploads/2019/11/py-spy_record_profile_1.png" style="width: 750px; height: 218px;" /></a><br />
	图片从上到下，标识了函数调用栈，X轴则表示函数的执行时间长短（颜色深浅不代表任何问题），越长的，表明该函数执行时间越长，这对性能分析很有用。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	而且更酷的是，如果你把生成的 svg 图片拉到一个浏览器窗口里查看，会发现它是&ldquo;可点击&rdquo;的，如果你把鼠标悬停在图片上，就会看到像上图一样的 tip 提示，在左下角还会显示出有当前鼠标指向的这个函数的统计信息，如果你不是悬停，而是点击这个函数所在的矩形区域，则会放大这个函数其下的区域，像极了一个可以导航的网页：<br />
	<img decoding="async" alt="py-spy profile" src="https://www.codelast.com/wp-content/uploads/2019/11/py-spy_record_profile_2.png" style="width: 750px; height: 216px;" /><br />
	在放大状态下，点击左上角的&ldquo;Reset Zoom&rdquo;就可以回到初始的未缩放状态。是不是很爽！</p>
<p>	py-spy 还有更多强大功能，请到其主页去进一步探索。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%a6%82%e4%bd%95%e6%9f%a5%e7%9c%8b%e4%b8%80%e4%b8%aapython%e8%bf%9b%e7%a8%8b%e5%9c%a8%e5%b9%b2%e4%bb%80%e4%b9%88%ef%bc%9a-py-spy-%e6%9d%a5%e5%b8%ae%e5%bf%99/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
