#!/usr/bin/env python

# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
A simple micro benchmark script which prints the speedup when using
Process.oneshot() ctx manager.
See: https://github.com/giampaolo/psutil/issues/799
"""

from __future__ import print_function
import sys
import time

import psutil


ITERATIONS = 1000

# The list of Process methods which gets collected in one shot and
# as such get advantage of the speedup.
if psutil.LINUX:
    names = (
        'cpu_percent',
        'cpu_times',
        'create_time',
        'gids',
        'name',
        'num_ctx_switches',
        'num_threads',
        'ppid',
        'status',
        'terminal',
        'uids',
    )
elif psutil.BSD:
    names = (
        'cpu_percent',
        'cpu_times',
        'create_time',
        'gids',
        'io_counters',
        'memory_full_info',
        'memory_info',
        'memory_percent',
        'num_ctx_switches',
        'ppid',
        'status',
        'terminal',
        'uids',
    )
elif psutil.SUNOS:
    names = (
        'cmdline',
        'create_time',
        'gids',
        'memory_full_info',
        'memory_info',
        'memory_percent',
        'name',
        'num_threads',
        'ppid',
        'status',
        'terminal',
        'uids',
    )
else:
    raise RuntimeError("platform %r not supported" % sys.platform)


def collect(p):
    return [getattr(p, n) for n in names]


def call(funs):
    for fun in funs:
        fun()


def main():
    p = psutil.Process()
    funs = collect(p)
    print("%s methods involved on platform %r (%s iterations):" % (
        len(names), sys.platform, ITERATIONS))
    for name in sorted(names):
        print("    " + name)

    # first "normal" run
    t = time.time()
    for x in range(ITERATIONS):
        call(funs)
    elapsed1 = time.time() - t
    print("normal:  %.3f secs" % elapsed1)

    # "one shot" run
    t = time.time()
    for x in range(ITERATIONS):
        with p.oneshot():
            call(funs)
    elapsed2 = time.time() - t
    print("oneshot: %.3f secs" % elapsed2)

    # done
    if elapsed2 < elapsed1:
        print("speedup: +%.2fx" % (elapsed1 / elapsed2))
    elif elapsed2 > elapsed1:
        print("slowdown: -%.2fx" % (elapsed1 / elapsed2))
    else:
        print("same speed")


main()

@@ -401,16 +401,34 @@
 ort time
+it%0Aimport textwrap
 %0A%0Aimport
@@ -1492,24 +1492,106 @@
 platform)%0A%0A%0A
+setup = textwrap.dedent(%22%22%22%0A    from __main__ import names%0A    import psutil%0A%0A    
 def collect(
@@ -1598,16 +1598,20 @@
 p):%0A    
+  
+  
 return %5B
@@ -1642,16 +1642,20 @@
 ames%5D%0A%0A%0A
+    
 def call
@@ -1662,24 +1662,28 @@
 (funs):%0A    
+ 
+   
 for fun in f
@@ -1687,16 +1687,20 @@
 n funs:%0A
+    
         
@@ -1710,21 +1710,8 @@
 ()%0A%0A
-%0Adef main():%0A
     
@@ -1753,16 +1753,39 @@
 lect(p)%0A
+    %22%22%22)%0A%0A%0Adef main():%0A
     prin
@@ -1985,105 +1985,78 @@
     
-t
+elapsed1
  = time
+it
 .time
-()%0A    for x in range(ITERATIONS):%0A        call(funs)%0A    elapsed1 = time.time() - t
+it(%22call(funs)%22, setup=setup, number=ITERATIONS)
 %0A   
@@ -2125,55 +2125,34 @@
     
+stm
 t = t
-ime.time()%0A    for x in range(ITERATIONS):
+extwrap.dedent(%22%22%22
 %0A   
@@ -2197,16 +2197,29 @@
 l(funs)%0A
+        %22%22%22)%0A
     elap
@@ -2233,19 +2233,55 @@
 time
+it
 .time
-() - t
+it(stmt, setup=setup, number=ITERATIONS)
 %0A   
@@ -2294,14 +2294,14 @@
 (%22on
-e
 shot:
+ 
  %25.3

use timeit module for doing benchmark