|
1
53
在Java服务器上,快速完成2-3个任务始终是一个巧妙的技巧 Ctrl键 - 打破 s并获取所有运行线程的2-3个线程转储。只需查看所有线程的“所在”位置,就可以非常快速地找出性能问题所在。 这种技术比我所知道的任何其他技术都能在2分钟内揭示更多的性能问题。 |
|
|
2
33
|
|
|
3
27
手动执行此操作实际上不能称为“快速”或“有效”,但有几种分析工具可以自动执行此操作;亦称为 statistical profiling . |
|
4
15
为什么? 正在调用一个函数。我经常使用它,但我使用自动化工具,例如 Luke Stackwalker OProfile 和各种硬件供应商提供的东西。 statistical power . 当一个函数占用运行时间的40%时,手动获取十个样本是可以的,因为平均而言,您将在其中获得四个样本,并且始终至少有一个。但是,如果您有一个平面配置文件,有数百个叶函数,没有一个占用超过运行时1.5%的时间,那么您需要更多的示例。 假设你有一个湖里有许多不同种类的鱼。如果湖中有40%的鱼是鲑鱼(还有60%是“其他所有的”),那么你只需要钓到10条鱼就知道湖中有很多鲑鱼。但如果你有数百种不同种类的鱼,而且每种鱼的数量都不超过1%,那么你需要捕到更多的鱼才能说“这个湖有0.8%的鲑鱼和0.6%的鳟鱼。”
我可以看一下 大旅行箱 函数,看,“我们在碰撞上花费了10%的时间”,但这并没有多大帮助:我需要确切地知道 哪里 在碰撞中,我知道要挤压哪些函数。只是“减少碰撞”只会让你走到这一步,尤其是当它意味着扔掉特性的时候。我更愿意知道“我们平均每帧花费600微秒在缓存的窄段丢失上 the octree 因为魔法导弹移动得如此之快,接触到许多细胞,“因为这样我就可以追踪到确切的修复方法:要么是更好的树,要么是更慢的导弹。
但卢克·斯塔克沃克(Luke Stackwalker)所做的本质是你所描述的:大约每毫秒,它就会停止程序并记录调用堆栈(包括调用的精确指令和行号) IP ).有些程序只需要成千上万个样本就可以有效地分析。
|
|
|
5
10
我知道很多程序员(包括我自己)都使用这种方法。它只会真正有助于发现最明显的性能问题,但它速度快、脏而且有效。 但我不会真的告诉其他程序员去做,因为我要花很长时间来解释所有的警告。基于这种方法很容易得出不准确的结论,而且在很多领域根本不起作用。(例如,该方法不会显示由用户输入触发的任何代码)。
|
|
6
10
评测是很棒的,而且当您能够做到这一点时,它肯定是一种更精确、更精确的方法。有时候你做不到,有一个可靠的后援是很好的。暂停技术就像当电动工具太远或电池耗尽时使用的手动螺丝刀。 Process Explorer ,我们可以看到线程堆栈的快照。您可以浏览堆栈的顶部,用enter键将其关闭,然后用另一次鼠标单击获取另一个快照。你可以很容易地每隔一秒钟左右得到一个样品。 不需要很长时间就可以看到堆栈的顶部通常位于数据库客户机库DLL(等待数据库)中,还是位于另一个系统DLL(等待系统操作)中,或者实际上位于应用程序本身的某些方法中。在本例中,如果我没记错的话,我们很快注意到10次中有8次应用程序在系统DLL文件调用中读取或写入网络文件。确实,最近的“升级”改变了文件共享的性能特征。没有一个快速的、肮脏的(系统管理员认可的)方法来查看应用程序在做什么 生产中 ,我们会花更多的时间来衡量问题,而不是纠正问题。 另一方面,当性能要求超出“足够好”以真正达到极限时,探查器就变得至关重要,这样您就可以尝试从所有紧密联系的前十或二十个热点中剔除周期。即使您只是在项目过程中试图保持适度的性能要求,当您能够获得正确的工具来帮助您进行测量和测试,甚至将它们集成到您的自动化测试过程中时,它也会非常有用。 但是当电源断了(可以说)电池没电时,知道如何使用手动螺丝刀就好了。
|
|
7
8
如果我们问“为什么它不更为人所知?”那么答案将是主观的。可能是因为评测提供了一个长期的解决方案,而不是当前的问题解决方案。它对于多线程应用程序无效,对于花费大量时间渲染的游戏等应用程序无效。
如果您有良好的检测代码,那么您可以检查的不仅仅是特定方法的使用时间;你可以看到所有的方法。 使用配置文件:
由于企业代码应该 总是 具有一定程度的剖析能力,因为它能在较长时间内为组织带来好处。代码越重要,进行的评测和测试就越多。 您的方法是有效的,并且是开发人员工具箱中的另一项。它只是被分析压倒了。 |
|
|
8
7
如果您必须避免使用探查器,更好的选择是使用记录器,然后将减速因子应用于“猜测”真正的问题所在。然而,分析器是更好的猜测工具。 在调试模式下点击暂停按钮可能无法给出应用程序行为的真实画面,原因是调试器引入了额外的可执行代码,这会减慢应用程序的某些部分。可以参考 Mike Stall's blog post 调试环境中应用程序速度减慢的可能原因。这篇文章揭示了某些原因,如断点太多、创建异常对象、未优化代码等。关于未优化代码的部分很重要,“调试”模式将导致大量优化(通常是代码排列和重新排序)被抛出窗口,以启用调试主机(运行代码的进程)和IDE来同步代码执行。因此,在“调试”模式下反复点击暂停可能是个坏主意。 |
|
9
7
|
|
10
6
堆栈跟踪快照仅允许您查看应用程序的频闪x射线。你可能需要更多的知识积累,而档案员可能会给你。
|
|
|
11
6
这些必须是一些琐碎的示例,您正在使用这些示例来使用您的方法获得有用的结果。我想不出哪一个项目的评测是有用的(无论采用何种方法),而您的“快速有效”方法能够获得令人满意的结果。启动和停止某些应用程序所需的时间已经使您的“快速”断言受到质疑。 同样,对于非平凡的程序,您提倡的方法是无用的。 编辑: 关于“为什么不更为人所知”? 根据我的经验,代码审查可以避免质量低劣的代码和算法,而分析也会发现这些问题。如果你想继续你的方法,那是很好的——但我认为对于大多数专业人士来说,这是一个很难尝试的事情,它永远不会得到积极的强化,因为这是一个很好的时间利用。 对于小样本集来说,这似乎是非常不准确的,而获取大样本集则需要花费大量时间,而这些时间本可以更好地用于其他有用的活动。 |
|
12
5
如果程序在运行中怎么办 生产 同时被付费客户或同事使用。探查器允许您在没有干扰的情况下进行观察(同样多,因为根据 Heisenberg principle ). 分析还可以为您提供更丰富、更详细、更准确的报告。从长远来看,这会更快。 |
|
|
13
4
不知何故,这种想法在英国流行开来,即绩效问题是通过衡量绩效来发现的。这是手段与目的的混淆。不知何故,很久以前我通过单步执行整个程序来避免这种情况。我并没有责备自己把它慢到了人的速度。我试着看看它是做错了还是做了不必要的事情。这就是如何使软件快速-查找并删除不必要的操作。
我 这就是为什么对调用堆栈进行采样不能给出错误的答案,以及为什么不需要很多样本。 在感兴趣的时间间隔内,当程序花费的时间超过您希望的时间时,调用堆栈将持续存在,即使您没有对其进行采样。 如果指令出现在M=2个或更多样本上,则在N个样本中,其P(I)约为M/N,且绝对有效。
因此,性能调优的过程很简单,只需挑选指令(主要是函数调用指令),这些指令通过打开调用堆栈的多个样本来提高性能。 那些是森林里的高大树木。 请注意,我们不必关心调用图,也不必关心函数需要多长时间,调用多少次,也不必关心递归。
您可以谈论林和树,但是对于任何可以通过修改代码来解决的性能问题,您需要修改指令,特别是具有高P(I)的指令。所以你需要知道他们在哪里,最好不要扮演福尔摩斯。堆栈采样告诉您它们的确切位置。 这种技术很难在多线程、事件驱动或生产系统中使用。如果剖析器能够报告P(I),那么这就是他们真正能够提供帮助的地方。 |
|
14
4
单步执行代码对于查看细节和故障排除算法非常有用。这就像是近距离观察一棵树,然后逐个跟踪树皮和树枝的每一条纹理。 通过分析,您可以看到全局,并快速确定问题点——比如向后退一步,看看整个森林,注意到最高的树。通过按执行时间长度对函数调用进行排序,可以快速识别出故障点所在的区域。 |
|
15
4
Commodore 64 BASIC 很多年以前。令人惊讶的是,它工作得如此之好。 |
|
16
3
我通常在超过时间片的实时程序上使用它。您不能手动停止和重新启动每秒必须运行60次的代码。 我还使用它来跟踪我编写的编译器中的瓶颈。你不想尝试手动破坏这样一个程序,因为你真的没有办法知道你是在瓶颈所在的地方破坏,还是仅仅在瓶颈之后,当操作系统被允许返回停止它时。另外,如果主要的瓶颈是你不能做任何事情,但你想摆脱系统中所有其他巨大的瓶颈怎么办?当您没有关于瓶颈位置的良好数据时,如何确定首先攻击哪些瓶颈的优先级 全部的 是,以及它们各自的相对影响是什么? |
|
|
17
3
程序越大,分析器就越有用。如果您需要优化包含数千个条件分支的程序,那么探查器是必不可少的。输入最大的测试数据样本,完成后将分析数据导入Excel。然后根据实际数据检查关于可能热点的假设。总有惊喜。 |
|
|
giantjenga · 优化整数向量到二进制向量的转换 1 年前 |
|
|
Daniel Lobo · 使用约束进行优化 1 年前 |
|
Sergio · python中大量数字的乘法 2 年前 |
|
|
Sergey Dev · 临时表与表变量 2 年前 |
|
|
John · 减少C中的内存消耗++ 2 年前 |