summaryrefslogtreecommitdiff
path: root/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/README.rst8
-rw-r--r--benchmarks/benchmarks/bench_function_base.py28
-rw-r--r--benchmarks/benchmarks/bench_io.py4
-rw-r--r--benchmarks/benchmarks/bench_lib.py5
-rw-r--r--benchmarks/benchmarks/bench_ma.py4
-rw-r--r--benchmarks/benchmarks/bench_overrides.py61
-rw-r--r--benchmarks/benchmarks/bench_reduce.py6
-rw-r--r--benchmarks/benchmarks/bench_shape_base.py8
8 files changed, 107 insertions, 17 deletions
diff --git a/benchmarks/README.rst b/benchmarks/README.rst
index f4f0b0de9..b67994ce0 100644
--- a/benchmarks/README.rst
+++ b/benchmarks/README.rst
@@ -60,3 +60,11 @@ Some things to consider:
- Preparing arrays etc. should generally be put in the ``setup`` method rather
than the ``time_`` methods, to avoid counting preparation time together with
the time of the benchmarked operation.
+
+- Be mindful that large arrays created with ``np.empty`` or ``np.zeros`` might
+ not be allocated in physical memory until the memory is accessed. If this is
+ desired behaviour, make sure to comment it in your setup function. If
+ you are benchmarking an algorithm, it is unlikely that a user will be
+ executing said algorithm on a newly created empty/zero array. One can force
+ pagefaults to occur in the setup phase either by calling ``np.ones`` or
+ ``arr.fill(value)`` after creating the array,
diff --git a/benchmarks/benchmarks/bench_function_base.py b/benchmarks/benchmarks/bench_function_base.py
index a45525793..9ef03262b 100644
--- a/benchmarks/benchmarks/bench_function_base.py
+++ b/benchmarks/benchmarks/bench_function_base.py
@@ -105,14 +105,6 @@ class Sort(Benchmark):
self.equal = np.ones(10000)
self.many_equal = np.sort(np.arange(10000) % 10)
- # quicksort median of 3 worst case
- self.worst = np.arange(1000000)
- x = self.worst
- while x.size > 3:
- mid = x.size // 2
- x[mid], x[-2] = x[-2], x[mid]
- x = x[:-2]
-
def time_sort(self):
np.sort(self.e)
@@ -128,9 +120,6 @@ class Sort(Benchmark):
def time_sort_many_equal(self):
self.many_equal.sort()
- def time_sort_worst(self):
- np.sort(self.worst)
-
def time_argsort(self):
self.e.argsort()
@@ -138,6 +127,23 @@ class Sort(Benchmark):
self.o.argsort()
+class SortWorst(Benchmark):
+ def setup(self):
+ # quicksort median of 3 worst case
+ self.worst = np.arange(1000000)
+ x = self.worst
+ while x.size > 3:
+ mid = x.size // 2
+ x[mid], x[-2] = x[-2], x[mid]
+ x = x[:-2]
+
+ def time_sort_worst(self):
+ np.sort(self.worst)
+
+ # Retain old benchmark name for backward compatability
+ time_sort_worst.benchmark_name = "bench_function_base.Sort.time_sort_worst"
+
+
class Where(Benchmark):
def setup(self):
self.d = np.arange(20000)
diff --git a/benchmarks/benchmarks/bench_io.py b/benchmarks/benchmarks/bench_io.py
index ce30c4345..879f9b69e 100644
--- a/benchmarks/benchmarks/bench_io.py
+++ b/benchmarks/benchmarks/bench_io.py
@@ -21,6 +21,10 @@ class Copy(Benchmark):
def time_memcpy(self, typename):
self.d[...] = self.e_d
+ def time_memcpy_large_out_of_place(self, typename):
+ l = np.ones(1024**2, dtype=np.dtype(typename))
+ l.copy()
+
def time_cont_assign(self, typename):
self.d[...] = 1
diff --git a/benchmarks/benchmarks/bench_lib.py b/benchmarks/benchmarks/bench_lib.py
index 83f26c9d1..e6c91a27c 100644
--- a/benchmarks/benchmarks/bench_lib.py
+++ b/benchmarks/benchmarks/bench_lib.py
@@ -19,7 +19,10 @@ class Pad(Benchmark):
]
def setup(self, shape, pad_width, mode):
- self.array = np.empty(shape)
+ # avoid np.zeros or np.empty's lazy allocation.
+ # np.full causes pagefaults to occur during setup
+ # instead of during the benchmark
+ self.array = np.full(shape, 0)
def time_pad(self, shape, pad_width, mode):
np.pad(self.array, pad_width, mode)
diff --git a/benchmarks/benchmarks/bench_ma.py b/benchmarks/benchmarks/bench_ma.py
index d313f01dc..aff78df0a 100644
--- a/benchmarks/benchmarks/bench_ma.py
+++ b/benchmarks/benchmarks/bench_ma.py
@@ -89,7 +89,9 @@ class Concatenate(Benchmark):
]
def setup(self, mode, n):
- normal = np.zeros((n, n), int)
+ # avoid np.zeros's lazy allocation that cause page faults during benchmark.
+ # np.fill will cause pagefaults to happen during setup.
+ normal = np.full((n, n), 0, int)
unmasked = np.ma.zeros((n, n), int)
masked = np.ma.array(normal, mask=True)
diff --git a/benchmarks/benchmarks/bench_overrides.py b/benchmarks/benchmarks/bench_overrides.py
new file mode 100644
index 000000000..2cb94c95c
--- /dev/null
+++ b/benchmarks/benchmarks/bench_overrides.py
@@ -0,0 +1,61 @@
+from __future__ import absolute_import, division, print_function
+
+from .common import Benchmark
+
+from numpy.core.overrides import array_function_dispatch
+import numpy as np
+
+
+def _broadcast_to_dispatcher(array, shape, subok=None):
+ return (array,)
+
+
+@array_function_dispatch(_broadcast_to_dispatcher)
+def mock_broadcast_to(array, shape, subok=False):
+ pass
+
+
+def _concatenate_dispatcher(arrays, axis=None, out=None):
+ for array in arrays:
+ yield array
+ if out is not None:
+ yield out
+
+
+@array_function_dispatch(_concatenate_dispatcher)
+def mock_concatenate(arrays, axis=0, out=None):
+ pass
+
+
+class DuckArray(object):
+ def __array_function__(self, func, types, args, kwargs):
+ pass
+
+
+class ArrayFunction(Benchmark):
+
+ def setup(self):
+ self.numpy_array = np.array(1)
+ self.numpy_arrays = [np.array(1), np.array(2)]
+ self.many_arrays = 500 * self.numpy_arrays
+ self.duck_array = DuckArray()
+ self.duck_arrays = [DuckArray(), DuckArray()]
+ self.mixed_arrays = [np.array(1), DuckArray()]
+
+ def time_mock_broadcast_to_numpy(self):
+ mock_broadcast_to(self.numpy_array, ())
+
+ def time_mock_broadcast_to_duck(self):
+ mock_broadcast_to(self.duck_array, ())
+
+ def time_mock_concatenate_numpy(self):
+ mock_concatenate(self.numpy_arrays, axis=0)
+
+ def time_mock_concatenate_many(self):
+ mock_concatenate(self.many_arrays, axis=0)
+
+ def time_mock_concatenate_duck(self):
+ mock_concatenate(self.duck_arrays, axis=0)
+
+ def time_mock_concatenate_mixed(self):
+ mock_concatenate(self.mixed_arrays, axis=0)
diff --git a/benchmarks/benchmarks/bench_reduce.py b/benchmarks/benchmarks/bench_reduce.py
index 353eb980c..ffc148cd2 100644
--- a/benchmarks/benchmarks/bench_reduce.py
+++ b/benchmarks/benchmarks/bench_reduce.py
@@ -29,8 +29,10 @@ class AddReduceSeparate(Benchmark):
class AnyAll(Benchmark):
def setup(self):
- self.zeros = np.zeros(100000, bool)
- self.ones = np.ones(100000, bool)
+ # avoid np.zeros's lazy allocation that would
+ # cause page faults during benchmark
+ self.zeros = np.full(100000, 0, bool)
+ self.ones = np.full(100000, 0, bool)
def time_all_fast(self):
self.zeros.all()
diff --git a/benchmarks/benchmarks/bench_shape_base.py b/benchmarks/benchmarks/bench_shape_base.py
index 716d1f9b5..e48ea0adb 100644
--- a/benchmarks/benchmarks/bench_shape_base.py
+++ b/benchmarks/benchmarks/bench_shape_base.py
@@ -23,7 +23,9 @@ class Block(Benchmark):
self.four_1d = np.ones(6 * n)
self.five_0d = np.ones(1 * n)
self.six_1d = np.ones(5 * n)
- self.zero_2d = np.zeros((2 * n, 6 * n))
+ # avoid np.zeros's lazy allocation that might cause
+ # page faults during benchmark
+ self.zero_2d = np.full((2 * n, 6 * n), 0)
self.one = np.ones(3 * n)
self.two = 2 * np.ones((3, 3 * n))
@@ -31,7 +33,9 @@ class Block(Benchmark):
self.four = 4 * np.ones(3 * n)
self.five = 5 * np.ones(1 * n)
self.six = 6 * np.ones(5 * n)
- self.zero = np.zeros((2 * n, 6 * n))
+ # avoid np.zeros's lazy allocation that might cause
+ # page faults during benchmark
+ self.zero = np.full((2 * n, 6 * n), 0)
def time_block_simple_row_wise(self, n):
np.block([self.a_2d, self.b_2d])