1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
#!/usr/bin/env python3
# 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 and print them from fastest to slowest.
$ make print_api_speed
SYSTEM APIS NUM CALLS SECONDS
-------------------------------------------------
disk_usage 300 0.00157
cpu_count 300 0.00255
pid_exists 300 0.00792
cpu_times 300 0.01044
boot_time 300 0.01136
cpu_percent 300 0.01290
cpu_times_percent 300 0.01515
virtual_memory 300 0.01594
users 300 0.01964
net_io_counters 300 0.02027
cpu_stats 300 0.02034
net_if_addrs 300 0.02962
swap_memory 300 0.03209
sensors_battery 300 0.05186
pids 300 0.07954
net_if_stats 300 0.09321
disk_io_counters 300 0.09406
cpu_count (cores) 300 0.10293
disk_partitions 300 0.10345
cpu_freq 300 0.20817
sensors_fans 300 0.63476
sensors_temperatures 231 2.00039
process_iter (all) 171 2.01300
net_connections 97 2.00206
PROCESS APIS NUM CALLS SECONDS
-------------------------------------------------
create_time 300 0.00009
exe 300 0.00015
nice 300 0.00057
ionice 300 0.00091
cpu_affinity 300 0.00091
cwd 300 0.00151
num_fds 300 0.00391
memory_info 300 0.00597
memory_percent 300 0.00648
io_counters 300 0.00707
name 300 0.00894
status 300 0.00900
ppid 300 0.00906
num_threads 300 0.00932
cpu_num 300 0.00933
num_ctx_switches 300 0.00943
uids 300 0.00979
gids 300 0.01002
cpu_times 300 0.01008
cmdline 300 0.01009
terminal 300 0.01059
is_running 300 0.01063
threads 300 0.01209
connections 300 0.01276
cpu_percent 300 0.01463
open_files 300 0.01630
username 300 0.01655
environ 300 0.02250
memory_full_info 300 0.07066
memory_maps 300 0.74281
"""
import argparse
import inspect
import os
import sys
from timeit import default_timer as timer
import psutil
from psutil._common import print_color
TIMES = 300
timings = []
templ = "{:<25} {:>10} {:>10}"
def print_header(what):
s = templ.format(what, "NUM CALLS", "SECONDS")
print_color(s, color=None, bold=True)
print("-" * len(s))
def print_timings():
timings.sort(key=lambda x: (x[1], -x[2]), reverse=True)
i = 0
while timings[:]:
title, times, elapsed = timings.pop(0)
s = templ.format(title, str(times), f"{elapsed:.5f}")
if i > len(timings) - 5:
print_color(s, color="red")
else:
print(s)
def timecall(title, fun, *args, **kw):
print("{:<50}".format(title), end="")
sys.stdout.flush()
t = timer()
for n in range(TIMES):
fun(*args, **kw)
elapsed = timer() - t
if elapsed > 2:
break
print("\r", end="")
sys.stdout.flush()
timings.append((title, n + 1, elapsed))
def set_highest_priority():
"""Set highest CPU and I/O priority (requires root)."""
p = psutil.Process()
if psutil.WINDOWS:
p.nice(psutil.HIGH_PRIORITY_CLASS)
else:
p.nice(-20)
if psutil.LINUX:
p.ionice(psutil.IOPRIO_CLASS_RT, value=7)
elif psutil.WINDOWS:
p.ionice(psutil.IOPRIO_HIGH)
def main():
global TIMES
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument('-t', '--times', type=int, default=TIMES)
args = parser.parse_args()
TIMES = args.times
assert TIMES > 1, TIMES
try:
set_highest_priority()
except psutil.AccessDenied:
prio_set = False
else:
prio_set = True
# --- 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_header("SYSTEM APIS")
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_header("PROCESS APIS")
ignore = [
'send_signal',
'suspend',
'resume',
'terminate',
'kill',
'wait',
'as_dict',
'parent',
'parents',
'oneshot',
'pid',
'rlimit',
'children',
]
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()
if not prio_set:
msg = "\nWARN: couldn't set highest process priority "
msg += "(requires root)"
print_color(msg, "red")
if __name__ == '__main__':
main()
|