我正在练习算法和数据结构。因此,我一直在分析我的程序。下面是来自gprof的一个示例输出:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ns/call ns/call name
29.76 2.58 2.58 _IO_vfscanf_internal
14.30 3.82 1.24 ____strtof_l_internal
11.71 4.84 1.02 memcpy
7.84 5.52 0.68 8400000 80.95 80.95 insertorupdate
5.94 6.03 0.52 _int_malloc
5.77 6.53 0.50 round_and_return
3.81 6.86 0.33 _IO_sputbackc
3.23 7.14 0.28 strlen
2.88 7.39 0.25 __strcmp_ia32
2.13 7.58 0.19 __isoc99_scanf
2.13 7.76 0.19 fgets
2.02 7.94 0.18 _IO_getline_info
1.27 8.05 0.11 __mpn_lshift
1.21 8.15 0.11 __memchr_sse2_bsf
0.87 8.23 0.08 malloc
... rest ...但我发现很难理解这意味着什么。例如,我的程序在标准函数上花费了很多时间,我想它应该是好的,对吗?因为,如果我的一个函数大部分时间都在消耗,那就意味着我做错了什么。但正如我所说,我不确定我是否正确地解释了这一点,因此,任何阅读这篇文章的建议或建议都是值得欢迎的。
发布于 2012-05-02 00:31:18
不是好的也不是坏的。
假设我告诉你,我花了45分钟从A点到B点,速度快吗?很慢吗?这是不是意味着我花了太多时间?还是不想?在我说A点是什么,B点是什么,以及我对速度的期望是什么之前,你什么都不能说。
分析器的结果相似。他们不会告诉你某些事情是绝对坏的,或者如果你的代码是完美的,从性能上讲。他们只是给你看原始的结果,让你解释和研究它们。
您可能有一个有效的情况,您的方法之一将花费大量的时间做某事,因为它需要花费大量的时间,因为它有很多工作要做。或者,这是一个迹象,表明您必须优化代码的这一部分,因为您期望这个方法至少比实际速度快一千倍。
分析通过给你一些提示来帮助你。以这种方式,SQL分析器可能很容易理解:
同样,代码分析器:
这意味着分析器的目的不是告诉您的代码是好的还是坏的- -这就是-的需求和验收测试,而是当您未能满足与性能相关的非功能需求时的瓶颈。
发布于 2012-05-02 11:19:13
在这种情况下,它要告诉您的是(正如目前正在编写的)您的程序正在花费大部分时间进行I/O操作。最前面的两个函数似乎都与从文件中读取数据有关。
memcpy是第三高的,几乎消耗了12%的时间,这部分(或者至少可能)有点令人不安。这也可能是读取输入的一部分(或多或少是不可避免的),但是如果您直接使用它,您可能想看看您使用它的位置和数量,看看是否可以更多地将数据放在同一个位置,并且(例如)重新排列指向它的指针,而不是移动数据块(但请记住,即使这样做也只会提高12%以下的速度)。
就数据结构和算法而言,这告诉您它们(显然)足够快,对整个运行时贡献很少。主要查看的地方是I/O,从事物的外观来看,大部分时间都用于调用fscanf (或其表亲之一)进行浮点转换。如果您关注的是总体速度(而不仅仅是您编写的算法),那么一个明显的可能性就是考虑以二进制格式存储数据,以避免从字符串转换为二进制数据。
发布于 2012-05-08 01:43:24
如果您正在使用算法并试图显示大O行为,最好计算基本操作,如比较或内存分配。
您在gprof输出中看到的是,程序将大部分时间用于阅读输入。这只是开放的CPU时间。它不计算I/O时间,即使你还在等待它。( I/O也是CPU时间,只是使用不同的CPU。)如果它也计算I/O时间,您将在代码中看到更大的部分。
gprof估计每个例程保存程序计数器的时间。它还计算每个例程从另一个例程调用的次数。从这个意义上说,它试图找出每个例程要花多少时间,或者花多少时间,或者花多少时间。它的计算方法充满了问题,正如最初的作者们自由承认的那样,它基本上保持了30年之久。这是值得尊敬的,但它不会告诉你多少,你可以依赖。
https://softwareengineering.stackexchange.com/questions/146810
复制相似问题