%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.py |
import numpy as np
import bottleneck as bn
from .autotimeit import autotimeit
__all__ = ["bench"]
def bench(
shapes=[(100,), (1000, 1000), (1000, 1000), (1000, 1000), (1000, 1000)],
axes=[0, 0, 0, 1, 1],
nans=[False, False, True, False, True],
dtype="float64",
order="C",
functions=None,
):
"""
Bottleneck benchmark.
Parameters
----------
shapes : list, optional
A list of tuple shapes of input arrays to use in the benchmark.
axes : list, optional
List of axes along which to perform the calculations that are being
benchmarked.
nans : list, optional
A list of the bools (True or False), one for each tuple in the
`shapes` list, that tells whether the input arrays should be randomly
filled with one-fifth NaNs.
dtype : str, optional
Data type string such as 'float64', which is the default.
order : {'C', 'F'}, optional
Whether to store multidimensional data in C- or Fortran-contiguous
(row- or column-wise) order in memory.
functions : {list, None}, optional
A list of strings specifying which functions to include in the
benchmark. By default (None) all functions are included in the
benchmark.
Returns
-------
A benchmark report is printed to stdout.
"""
if len(shapes) != len(nans):
raise ValueError("`shapes` and `nans` must have the same length")
if len(shapes) != len(axes):
raise ValueError("`shapes` and `axes` must have the same length")
# Header
print("Bottleneck performance benchmark")
print(" Bottleneck %s; Numpy %s" % (bn.__version__, np.__version__))
print(" Speed is NumPy time divided by Bottleneck time")
print(" NaN means approx one-fifth NaNs; %s used" % str(dtype))
print("")
header = [" " * 11]
for nan in nans:
if nan:
header.append("NaN".center(11))
else:
header.append("no NaN".center(11))
print("".join(header))
header = ["".join(str(shape).split(" ")).center(11) for shape in shapes]
header = [" " * 12] + header
print("".join(header))
header = ["".join(("axis=" + str(axis)).split(" ")).center(11) for axis in axes]
header = [" " * 12] + header
print("".join(header))
suite = benchsuite(shapes, dtype, nans, axes, order, functions)
for test in suite:
name = test["name"].ljust(12)
fmt = name + "%7.1f" + "%11.1f" * (len(shapes) - 1)
speed = timer(test["statements"], test["setups"])
print(fmt % tuple(speed))
def timer(statements, setups):
speed = []
if len(statements) != 2:
raise ValueError("Two statements needed.")
for setup in setups:
with np.errstate(invalid="ignore"):
t0 = autotimeit(statements[0], setup)
t1 = autotimeit(statements[1], setup)
speed.append(t1 / t0)
return speed
def getarray(shape, dtype, nans, order):
a = np.arange(np.prod(shape), dtype=dtype)
if nans and issubclass(a.dtype.type, np.inexact):
a[::5] = np.nan
rs = np.random.RandomState(shape)
rs.shuffle(a)
return np.array(a.reshape(*shape), order=order)
def benchsuite(shapes, dtype, nans, axes, order, functions):
suite = []
def getsetups(setup, shapes, nans, axes, dtype, order):
template = """
from bottleneck.benchmark.bench import getarray
a = getarray(%s, '%s', %s, '%s')
axis=%s
%s"""
setups = []
for shape, axis, nan in zip(shapes, axes, nans):
s = template % (
str(shape),
str(dtype),
str(nan),
str(order),
str(axis),
setup,
)
s = "\n".join([line.strip() for line in s.split("\n")])
setups.append(s)
return setups
# non-moving window functions
funcs = bn.get_functions("reduce", as_string=True)
funcs += ["rankdata", "nanrankdata"]
for func in funcs:
if functions is not None and func not in functions:
continue
run = {}
run["name"] = func
run["statements"] = ["bn_func(a, axis)", "sl_func(a, axis)"]
setup = """
from bottleneck import %s as bn_func
try: from numpy import %s as sl_func
except ImportError: from bottleneck.slow import %s as sl_func
if "%s" == "median": from bottleneck.slow import median as sl_func
""" % (
func,
func,
func,
func,
)
run["setups"] = getsetups(setup, shapes, nans, axes, dtype, order)
suite.append(run)
# partition, argpartition
funcs = ["partition", "argpartition"]
for func in funcs:
if functions is not None and func not in functions:
continue
run = {}
run["name"] = func
run["statements"] = ["bn_func(a, n, axis)", "sl_func(a, n, axis)"]
setup = """
from bottleneck import %s as bn_func
from bottleneck.slow import %s as sl_func
if axis is None: n = a.size
else: n = a.shape[axis] - 1
n = max(n // 2, 0)
""" % (
func,
func,
)
run["setups"] = getsetups(setup, shapes, nans, axes, dtype, order)
suite.append(run)
# replace, push
funcs = ["replace", "push"]
for func in funcs:
if functions is not None and func not in functions:
continue
run = {}
run["name"] = func
if func == "replace":
run["statements"] = ["bn_func(a, nan, 0)", "slow_func(a, nan, 0)"]
elif func == "push":
run["statements"] = ["bn_func(a, 5, axis)", "slow_func(a, 5, axis)"]
else:
raise ValueError("Unknow function name")
setup = """
from numpy import nan
from bottleneck import %s as bn_func
from bottleneck.slow import %s as slow_func
""" % (
func,
func,
)
run["setups"] = getsetups(setup, shapes, nans, axes, dtype, order)
suite.append(run)
# moving window functions
funcs = bn.get_functions("move", as_string=True)
for func in funcs:
if functions is not None and func not in functions:
continue
run = {}
run["name"] = func
run["statements"] = ["bn_func(a, w, 1, axis)", "sw_func(a, w, 1, axis)"]
setup = """
from bottleneck.slow.move import %s as sw_func
from bottleneck import %s as bn_func
w = a.shape[axis] // 5
""" % (
func,
func,
)
run["setups"] = getsetups(setup, shapes, nans, axes, dtype, order)
suite.append(run)
return suite