python performance measure 02

02. 性能验证

方法01:

##利用python的标准库cProfile结合pstats,进行显示。

##nova/api/openstack/wsgi.py

class Resource(wsgi.Application):
    def __call__(self, request):
        import time
        import cProfile, pstats, StringIO
        from oslo_middleware import request_id

        pr = cProfile.Profile()
        pr.enable() # Start collecting profiling data.
        start_time = time.time()

        doSomething()
        # rst = self._process_stack(request, action, action_args, content_type, body, accept)
        end_time = time.time()
        pr.disable() # Stop collecting profiling data.
        s = StringIO.StringIO()
        sortby = 'cumulative'
        ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
        ps.print_stats() # Create a Stats object based on the current profile and print the results to stdout.
        req_id = request.environ.get(request_id.ENV_REQUEST_ID)
        p = open("/tmp/test/" + str(req_id),'w')
        p.write(s.getvalue())
        p.close()
        #return rst

 结果:

         217872 function calls (207700 primitive calls) in 0.701 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      2/1    0.000    0.000    0.700    0.700 /usr/lib/python2.7/site-packages/nova/api/openstack/wsgi.py:694(_process_stack)
        1    0.000    0.000    0.698    0.698 /usr/lib/python2.7/site-packages/nova/api/openstack/wsgi.py:599(post_process_extensions)
        1    0.000    0.000    0.415    0.415 /usr/lib/python2.7/site-packages/nova/api/openstack/compute/security_groups.py:489(detail)
        4    0.000    0.000    0.350    0.088 /usr/lib/python2.7/site-packages/oslo_versionedobjects/base.py:167(wrapper)
       96    0.002    0.000    0.306    0.003 /usr/lib/python2.7/site-packages/eventlet/hubs/__init__.py:124(trampoline)
        1    0.000    0.000    0.302    0.302 /usr/lib/python2.7/site-packages/nova/api/openstack/compute/security_groups.py:435(_extend_servers)

ncalls
    for the number of calls,
tottime
    for the total time spent in the given function (and excluding time made in calls to sub-functions)
percall
    is the quotient of tottime divided by ncalls
cumtime
    is the cumulative time spent in this and all subfunctions (from invocation till exit). This figure is accurate even for recursive functions.
percall
    is the quotient of cumtime divided by primitive calls
filename:lineno(function)
    provides the respective data of each function

方法02:

##利用line_profiler,需要python3.3以后的版本,卒。

参考:https://github.com/rkern/line_profiler

方法03:

##利用memeory_profiler, 查看内存的使用情况。

D:\Workspace\_mock>python -m memory_profiler test.py
hello world
Filename: test.py

Line #    Mem usage    Increment   Line Contents
================================================
     2   12.328 MiB    0.000 MiB   @profile    ##这个profile需要加上
     3                             def test():
     4   12.340 MiB    0.012 MiB       print "hello world"

方法04:

## 利用objgraph进行两个show_growth点之间看到哪些对象被增加或是删除了。

import objgraph
objgraph.show_most_common_types()
print "----------"
objgraph.show_growth()

def test():
    a=[]
    b=[1,2,3]
    print "hello world"
    objgraph.show_growth()
    c=[]
    print "hello objgraph"
    objgraph.show_growth()    
    d=[2,3,4]
    objgraph.show_growth()

test()

D:\Workspace\_mock>python test.py
wrapper_descriptor         1235
function                   1166
builtin_function_or_method 888
method_descriptor          644
dict                       527
weakref                    376
tuple                      342
member_descriptor          318
list                       213
getset_descriptor          187
----------
wrapper_descriptor             1244     +1244
function                       1166     +1166
builtin_function_or_method      888      +888
method_descriptor               644      +644
dict                            515      +515
weakref                         378      +378
member_descriptor               321      +321
tuple                           244      +244
list                            213      +213
getset_descriptor               191      +191
hello world
list          215        +2
function     1167        +1
frame           4        +1
hello objgraph
list      216        +1
list      217        +1

 

方法05:

#利用guppy, 这个包可以知道在代码执行的每个阶段中,每种类型(str、tuple、dict等)分别创建了多少对象。

import random
from guppy import hpy
 
def random_sort(n):
    hp = hpy()
    print "Heap at the beginning of the functionn", hp.heap()
    l = [random.random() for i in range(n)]
    l.sort()
    print "Heap at the end of the functionn", hp.heap()
    return l
 
if __name__ == "__main__":
    random_sort(100)
    
D:\Workspace\_mock>python test.py
Heap at the beginning of the functionn Partition of a set of 28275 objects. Total size = 2036712 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  12480  44   723148  36    723148  36 str
     1   6326  22   256776  13    979924  48 tuple
     2    325   1   161660   8   1141584  56 dict (no owner)
     3   1719   6   123768   6   1265352  62 types.CodeType
     4     83   0   118372   6   1383724  68 dict of module
     5    216   1   112032   6   1495756  73 dict of type
     6   1658   6    99480   5   1595236  78 function
     7    216   1    96028   5   1691264  83 type
     8    124   0    68048   3   1759312  86 dict of class
     9   1066   4    42640   2   1801952  88 __builtin__.wrapper_descriptor
<96 more rows. Type e.g. '_.more' to view.>
Heap at the end of the functionn Partition of a set of 2028285 objects. Total size = 42426492 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0 2000082  99 32001312  75  32001312  75 float
     1    188   0  8401872  20  40403184  95 list
     2  12482   1   723236   2  41126420  97 str
     3   6325   0   256744   1  41383164  98 tuple
     4    331   0   162500   0  41545664  98 dict (no owner)
     5   1719   0   123768   0  41669432  98 types.CodeType
     6     83   0   118372   0  41787804  98 dict of module
     7    216   0   112032   0  41899836  99 dict of type
     8   1657   0    99420   0  41999256  99 function
     9    216   0    96028   0  42095284  99 type
<96 more rows. Type e.g. '_.more' to view.>
    

 

小结:

目前实用最多的还是方法1,比较快捷、直接。

posted on 2017-09-19 08:55  yaoweilei  阅读(254)  评论(0编辑  收藏  举报

导航