%PDF- %PDF-
| Direktori : /backups/router/usr/local/lib/python3.11/site-packages/bottleneck/benchmark/ |
| Current File : //backups/router/usr/local/lib/python3.11/site-packages/bottleneck/benchmark/bench_detailed.py |
import numpy as np
import bottleneck as bn
from .autotimeit import autotimeit
__all__ = ["bench_detailed"]
def bench_detailed(function="nansum", fraction_nan=0.0):
"""
Benchmark a single function in detail or, optionally, all functions.
Parameters
----------
function : str, optional
Name of function, as a string, to benchmark. Default ('nansum') is
to benchmark bn.nansum. If `function` is 'all' then detailed
benchmarks are run on all bottleneck functions.
fraction_nan : float, optional
Fraction of array elements that should, on average, be NaN. The
default (0.0) is not to set any elements to NaN.
Returns
-------
A benchmark report is printed to stdout.
"""
if function == "all":
# benchmark all bottleneck functions
funcs = bn.get_functions("all", as_string=True)
funcs.sort()
for func in funcs:
bench_detailed(func, fraction_nan)
if fraction_nan < 0 or fraction_nan > 1:
raise ValueError("`fraction_nan` must be between 0 and 1, inclusive")
tab = " "
# Header
print("%s benchmark" % function)
print("%sBottleneck %s; Numpy %s" % (tab, bn.__version__, np.__version__))
print("%sSpeed is NumPy time divided by Bottleneck time" % tab)
if fraction_nan == 0:
print("%sNone of the array elements are NaN" % tab)
else:
print(
"%s%.1f%% of the array elements are NaN (on average)"
% (tab, fraction_nan * 100)
)
print("")
print(" Speed Call Array")
suite = benchsuite(function, fraction_nan)
for test in suite:
name = test["name"]
speed = timer(test["statements"], test["setup"], test["repeat"])
print("%8.1f %s %s" % (speed, name[0].ljust(27), name[1]))
def timer(statements, setup, repeat):
if len(statements) != 2:
raise ValueError("Two statements needed.")
with np.errstate(invalid="ignore"):
t0 = autotimeit(statements[0], setup, repeat=repeat)
t1 = autotimeit(statements[1], setup, repeat=repeat)
speed = t1 / t0
return speed
def benchsuite(function, fraction_nan):
# setup is called before each run of each function
setup = """
from bottleneck import %s as bn_fn
try: from numpy import %s as sl_fn
except ImportError: from bottleneck.slow import %s as sl_fn
# avoid all-nan slice warnings from np.median and np.nanmedian
if "%s" == "median": from bottleneck.slow import median as sl_fn
if "%s" == "nanmedian": from bottleneck.slow import nanmedian as sl_fn
from numpy import array, nan
from numpy.random import RandomState
rand = RandomState(123).rand
a = %s
if %s != 0: a[a < %s] = nan
"""
setup = "\n".join([s.strip() for s in setup.split("\n")])
# what kind of function signature do we need to use?
if function in bn.get_functions("reduce", as_string=True):
index = 0
elif function in ["rankdata", "nanrankdata"]:
index = 0
elif function in bn.get_functions("move", as_string=True):
index = 1
elif function in ["partition", "argpartition", "push"]:
index = 2
elif function == "replace":
index = 3
else:
raise ValueError("`function` (%s) not recognized" % function)
# create benchmark suite
instructions = get_instructions()
f = function
suite = []
for instruction in instructions:
signature = instruction[index + 1]
if signature is None:
continue
array = instruction[0]
repeat = instruction[-1]
run = {}
run["name"] = [f + signature, array]
run["statements"] = ["bn_fn" + signature, "sl_fn" + signature]
run["setup"] = setup % (f, f, f, f, f, array, fraction_nan, fraction_nan)
run["repeat"] = repeat
suite.append(run)
return suite
def get_instructions():
instructions = [
# 1d input array
(
"rand(1)",
"(a)", # reduce + (nan)rankdata
"(a, 1)", # move
"(a, 0)", # (arg)partition
"(a, np.nan, 0)", # replace
10,
),
("rand(10)", "(a)", "(a, 2)", "(a, 2)", "(a, np.nan, 0)", 10),
("rand(100)", "(a)", "(a, 20)", "(a, 20)", "(a, np.nan, 0)", 6),
("rand(1000)", "(a)", "(a, 200)", "(a, 200)", "(a, np.nan, 0)", 3),
("rand(1000000)", "(a)", "(a, 200)", "(a, 200)", "(a, np.nan, 0)", 2),
# 2d input array
("rand(10, 10)", "(a)", "(a, 2)", "(a, 2)", "(a, np.nan, 0)", 6),
("rand(100, 100)", "(a)", "(a, 20)", "(a, 20)", "(a, np.nan, 0)", 3),
("rand(1000, 1000)", "(a)", "(a, 200)", "(a, 200)", "(a, np.nan, 0)", 2),
("rand(10, 10)", "(a, 1)", None, None, None, 6),
("rand(100, 100)", "(a, 1)", None, None, None, 3),
("rand(1000, 1000)", "(a, 1)", None, None, None, 2),
("rand(100000, 2)", "(a, 1)", "(a, 1)", "(a, 1)", None, 2),
("rand(10, 10)", "(a, 0)", None, None, None, 6),
("rand(100, 100)", "(a, 0)", "(a, 20, axis=0)", None, None, 3),
("rand(1000, 1000)", "(a, 0)", "(a, 200, axis=0)", None, None, 2),
# 3d input array
(
"rand(100, 100, 100)",
"(a, 0)",
"(a, 20, axis=0)",
"(a, 20, axis=0)",
None,
2,
),
(
"rand(100, 100, 100)",
"(a, 1)",
"(a, 20, axis=1)",
"(a, 20, axis=1)",
None,
2,
),
(
"rand(100, 100, 100)",
"(a, 2)",
"(a, 20, axis=2)",
"(a, 20, axis=2)",
"(a, np.nan, 0)",
2,
),
# 0d input array
("array(1.0)", "(a)", None, None, "(a, 0, 2)", 10),
]
return instructions