@@ -153,15 +153,34 @@ class SortGenerator:
153153 # The size of the "partially ordered" sub-arrays
154154 BUBBLE_SIZE = 100
155155
156+ small_limits = {
157+ 'bool' : (0 , 2 ),
158+ 'uint8' : (0 , 256 ),
159+ 'int8' : (- 128 , 128 ),
160+ 'int16' : (- 32768 , 32768 ),
161+ 'float16' : (- 1000 , 1000 ),
162+ }
163+
164+ @staticmethod
165+ @memoize
166+ def ordered_range (size , dtype ):
167+ """
168+ Returns an ordered array of the given size and dtype.
169+ """
170+ if dtype in SortGenerator .small_limits :
171+ arange = np .arange (* SortGenerator .small_limits [dtype ], dtype = dtype )
172+ return np .repeat (arange , size // arange .size + 1 )[:size ]
173+ else :
174+ return np .arange (size , dtype = dtype )
175+
156176 @staticmethod
157177 @memoize
158178 def random (size , dtype , rnd ):
159179 """
160180 Returns a randomly-shuffled array.
161181 """
162- arr = np . arange (size , dtype = dtype )
182+ arr = SortGenerator . ordered_range (size , dtype = dtype )
163183 rnd = np .random .RandomState (1792364059 )
164- np .random .shuffle (arr )
165184 rnd .shuffle (arr )
166185 return arr
167186
@@ -171,22 +190,15 @@ def ordered(size, dtype, rnd):
171190 """
172191 Returns an ordered array.
173192 """
174- return np . arange (size , dtype = dtype )
193+ return SortGenerator . ordered_range (size , dtype = dtype )
175194
176195 @staticmethod
177196 @memoize
178197 def reversed (size , dtype , rnd ):
179198 """
180199 Returns an array that's in descending order.
181200 """
182- dtype = np .dtype (dtype )
183- try :
184- with np .errstate (over = "raise" ):
185- res = dtype .type (size - 1 )
186- except (OverflowError , FloatingPointError ):
187- raise SkipNotImplemented ("Cannot construct arange for this size." )
188-
189- return np .arange (size - 1 , - 1 , - 1 , dtype = dtype )
201+ return SortGenerator .ordered_range (size , dtype = dtype )[::- 1 ]
190202
191203 @staticmethod
192204 @memoize
@@ -202,7 +214,7 @@ def sorted_block(size, dtype, block_size, rnd):
202214 """
203215 Returns an array with blocks that are all sorted.
204216 """
205- a = np . arange (size , dtype = dtype )
217+ a = SortGenerator . ordered_range (size , dtype = dtype )
206218 b = []
207219 if size < block_size :
208220 return a
@@ -219,10 +231,20 @@ class Sort(Benchmark):
219231 real-world applications.
220232 """
221233 params = [
222- # In NumPy 1.17 and newer, 'merge' can be one of several
223- # stable sorts, it isn't necessarily merge sort.
224- ['quick' , 'merge' , 'heap' ],
225- ['float64' , 'int64' , 'float32' , 'uint32' , 'int32' , 'int16' , 'float16' ],
234+ [True , False ],
235+ [True , False ],
236+ [
237+ 'float64' ,
238+ 'int64' ,
239+ 'float32' ,
240+ 'uint32' ,
241+ 'int32' ,
242+ 'int16' ,
243+ 'float16' ,
244+ 'uint8' ,
245+ 'int8' ,
246+ 'bool' ,
247+ ],
226248 [
227249 ('random' ,),
228250 ('ordered' ,),
@@ -233,25 +255,36 @@ class Sort(Benchmark):
233255 ('sorted_block' , 1000 ),
234256 ],
235257 ]
236- param_names = ['kind ' , 'dtype' , 'array_type' ]
258+ param_names = ['stable' , 'descending ' , 'dtype' , 'array_type' ]
237259
238260 # The size of the benchmarked arrays.
239261 ARRAY_SIZE = 1000000
240262
241- def setup (self , kind , dtype , array_type ):
263+ def setup (self , stable , descending , dtype , array_type ):
242264 rnd = np .random .RandomState (507582308 )
243265 array_class = array_type [0 ]
244266 generate_array_method = getattr (SortGenerator , array_class )
245267 self .arr = generate_array_method (self .ARRAY_SIZE , dtype , * array_type [1 :], rnd )
268+ if descending :
269+ self .arr = self .arr [::- 1 ]
270+ self .arr = self .arr .copy ()
246271
247- def time_sort (self , kind , dtype , array_type ):
272+ def time_sort (self , stable , descending , dtype , array_type ):
248273 # Using np.sort(...) instead of arr.sort(...) because it makes a copy.
249274 # This is important because the data is prepared once per benchmark, but
250275 # used across multiple runs.
251- np .sort (self .arr , kind = kind )
252-
253- def time_argsort (self , kind , dtype , array_type ):
254- np .argsort (self .arr , kind = kind )
276+ if descending :
277+ np .sort (self .arr , stable = stable , descending = True )
278+ else :
279+ # for backward compatibility to NumPy 2.0
280+ np .sort (self .arr , stable = stable )
281+
282+ def time_argsort (self , stable , descending , dtype , array_type ):
283+ if descending :
284+ np .argsort (self .arr , stable = stable , descending = True )
285+ else :
286+ # for backward compatibility to NumPy 2.0
287+ np .argsort (self .arr , stable = stable )
255288
256289
257290class Partition (Benchmark ):
0 commit comments