1"""Benchmarks for `numpy.lib`.""" 2 3 4from .common import Benchmark 5 6import numpy as np 7 8 9class Pad(Benchmark): 10 """Benchmarks for `numpy.pad`. 11 12 When benchmarking the pad function it is useful to cover scenarios where 13 the ratio between the size of the input array and the output array differs 14 significantly (original area vs. padded area). This allows to evaluate for 15 which scenario a padding algorithm is optimized. Furthermore involving 16 large range of array sizes ensures that the effects of CPU-bound caching is 17 visible. 18 19 The table below shows the sizes of the arrays involved in this benchmark: 20 21 +-----------------+----------+-----------+-----------+-----------------+ 22 | shape | original | padded: 1 | padded: 8 | padded: (0, 32) | 23 +=================+==========+===========+===========+=================+ 24 | (2 ** 22,) | 32 MiB | 32.0 MiB | 32.0 MiB | 32.0 MiB | 25 +-----------------+----------+-----------+-----------+-----------------+ 26 | (1024, 1024) | 8 MiB | 8.03 MiB | 8.25 MiB | 8.51 MiB | 27 +-----------------+----------+-----------+-----------+-----------------+ 28 | (256, 256, 1) | 256 KiB | 786 KiB | 5.08 MiB | 11.6 MiB | 29 +-----------------+----------+-----------+-----------+-----------------+ 30 | (4, 4, 4, 4) | 2 KiB | 10.1 KiB | 1.22 MiB | 12.8 MiB | 31 +-----------------+----------+-----------+-----------+-----------------+ 32 | (1, 1, 1, 1, 1) | 8 B | 1.90 MiB | 10.8 MiB | 299 MiB | 33 +-----------------+----------+-----------+-----------+-----------------+ 34 """ 35 36 param_names = ["shape", "pad_width", "mode"] 37 params = [ 38 # Shape of the input arrays 39 [(2 ** 22,), (1024, 1024), (256, 128, 1), 40 (4, 4, 4, 4), (1, 1, 1, 1, 1)], 41 # Tested pad widths 42 [1, 8, (0, 32)], 43 # Tested modes: mean, median, minimum & maximum use the same code path 44 # reflect & symmetric share a lot of their code path 45 ["constant", "edge", "linear_ramp", "mean", "reflect", "wrap"], 46 ] 47 48 def setup(self, shape, pad_width, mode): 49 # Make sure to fill the array to make the OS page fault 50 # in the setup phase and not the timed phase 51 self.array = np.full(shape, fill_value=1, dtype=np.float64) 52 53 def time_pad(self, shape, pad_width, mode): 54 np.pad(self.array, pad_width, mode) 55 56class Nan(Benchmark): 57 """Benchmarks for nan functions""" 58 59 param_names = ["array_size", "percent_nans"] 60 params = [ 61 # sizes of the 1D arrays 62 [200, int(2e5)], 63 # percent of np.nan in arrays 64 [0, 0.1, 2., 50., 90.], 65 ] 66 67 def setup(self, array_size, percent_nans): 68 np.random.seed(123) 69 # produce a randomly shuffled array with the 70 # approximate desired percentage np.nan content 71 base_array = np.random.uniform(size=array_size) 72 base_array[base_array < percent_nans / 100.] = np.nan 73 self.arr = base_array 74 75 def time_nanmin(self, array_size, percent_nans): 76 np.nanmin(self.arr) 77 78 def time_nanmax(self, array_size, percent_nans): 79 np.nanmax(self.arr) 80 81 def time_nanargmin(self, array_size, percent_nans): 82 np.nanargmin(self.arr) 83 84 def time_nanargmax(self, array_size, percent_nans): 85 np.nanargmax(self.arr) 86 87 def time_nansum(self, array_size, percent_nans): 88 np.nansum(self.arr) 89 90 def time_nanprod(self, array_size, percent_nans): 91 np.nanprod(self.arr) 92 93 def time_nancumsum(self, array_size, percent_nans): 94 np.nancumsum(self.arr) 95 96 def time_nancumprod(self, array_size, percent_nans): 97 np.nancumprod(self.arr) 98 99 def time_nanmean(self, array_size, percent_nans): 100 np.nanmean(self.arr) 101 102 def time_nanvar(self, array_size, percent_nans): 103 np.nanvar(self.arr) 104 105 def time_nanstd(self, array_size, percent_nans): 106 np.nanstd(self.arr) 107 108 def time_nanmedian(self, array_size, percent_nans): 109 np.nanmedian(self.arr) 110 111 def time_nanquantile(self, array_size, percent_nans): 112 np.nanquantile(self.arr, q=0.2) 113 114 def time_nanpercentile(self, array_size, percent_nans): 115 np.nanpercentile(self.arr, q=50) 116