blob: a99293c458c3b9a9f7cf19f98efce325095e865e [file] [edit]
#!/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.
"""Benchmark all API calls.
$ make print_api_speed
SYSTEM APIS SECONDS
----------------------------------
boot_time 0.000140
cpu_count 0.000016
cpu_count (cores) 0.000312
cpu_freq 0.000811
cpu_percent 0.000138
cpu_stats 0.000165
cpu_times 0.000140
...
PROCESS APIS SECONDS
----------------------------------
children 0.007246
cmdline 0.000069
connections 0.000072
cpu_affinity 0.000012
cpu_num 0.000035
cpu_percent 0.000042
cpu_times 0.000031
"""
from __future__ import print_function, division
from timeit import default_timer as timer
import argparse
import inspect
import os
import psutil
from scriptutils import hilite
SORT_BY_TIME = False if psutil.POSIX else True
TOP_SLOWEST = 7
timings = []
templ = "%-25s %s"
def print_timings():
slower = []
timings.sort(key=lambda x: x[1 if SORT_BY_TIME else 0])
for x in sorted(timings, key=lambda x: x[1], reverse=1)[:TOP_SLOWEST]:
slower.append(x[0])
while timings[:]:
title, elapsed = timings.pop(0)
s = templ % (title, "%f" % elapsed)
if title in slower:
s = hilite(s, ok=False)
print(s)
def timecall(title, fun, *args, **kw):
t = timer()
fun(*args, **kw)
elapsed = timer() - t
timings.append((title, elapsed))
def titlestr(s):
return hilite(s, ok=None, bold=True)
def run():
# --- system
public_apis = []
ignore = ['wait_procs', 'process_iter', 'win_service_get',
'win_service_iter']
if psutil.MACOS:
ignore.append('net_connections') # raises AD
for name in psutil.__all__:
obj = getattr(psutil, name, None)
if inspect.isfunction(obj):
if name not in ignore:
public_apis.append(name)
print(titlestr(templ % ("SYSTEM APIS", "SECONDS")))
print("-" * 34)
for name in public_apis:
fun = getattr(psutil, name)
args = ()
if name == 'pid_exists':
args = (os.getpid(), )
elif name == 'disk_usage':
args = (os.getcwd(), )
timecall(name, fun, *args)
timecall('cpu_count (cores)', psutil.cpu_count, logical=False)
timecall('process_iter (all)', lambda: list(psutil.process_iter()))
print_timings()
# --- process
print("")
print(titlestr(templ % ("PROCESS APIS", "SECONDS")))
print("-" * 34)
ignore = ['send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
'as_dict', 'parent', 'parents', 'memory_info_ex', 'oneshot',
'pid', 'rlimit']
if psutil.MACOS:
ignore.append('memory_maps') # XXX
p = psutil.Process()
for name in sorted(dir(p)):
if not name.startswith('_') and name not in ignore:
fun = getattr(p, name)
timecall(name, fun)
print_timings()
def main():
global SORT_BY_TIME, TOP_SLOWEST
parser = argparse.ArgumentParser(description='Benchmark all API calls')
parser.add_argument('-t', '--time', required=False, default=SORT_BY_TIME,
action='store_true', help="sort by timings")
parser.add_argument('-s', '--slowest', required=False, default=TOP_SLOWEST,
help="highlight the top N slowest APIs")
args = parser.parse_args()
SORT_BY_TIME = bool(args.time)
TOP_SLOWEST = int(args.slowest)
run()
if __name__ == '__main__':
main()