@@ -84,122 +84,67 @@ def timer_uniform():
84
84
run_timer (dist , command , None , SETUP , 'Uniforms' )
85
85
86
86
87
- def timer_8bit_bounded (max = 95 , use_masked = True ):
88
- min = 0
87
+ def timer_bounded (bits = 8 , max = 95 , use_masked = True ):
88
+ """
89
+ Timer for 8-bit bounded values.
90
+
91
+ Parameters
92
+ ----------
93
+ bits : {8, 16, 32, 64}
94
+ Bit width of unsigned output type
95
+ max : int
96
+ Upper bound for range. Lower is always 0. Must be <= 2**bits.
97
+ use_masked: bool
98
+ If True, masking and rejection sampling is used to generate a random
99
+ number in an interval. If False, Lemire's algorithm is used if
100
+ available to generate a random number in an interval.
101
+
102
+ Notes
103
+ -----
104
+ Lemire's algorithm has improved performance when {max}+1 is not a
105
+ power of two.
106
+ """
107
+ if bits not in (8 , 16 , 32 , 64 ):
108
+ raise ValueError ('bits must be one of 8, 16, 32, 64.' )
109
+ minimum = 0
89
110
90
111
dist = 'random_uintegers'
91
112
92
- # Note on performance of generating random numbers in an interval:
93
- # use_masked=True : masking and rejection sampling is used to generate a random number in an interval.
94
- # use_masked=False : Lemire's algorithm is used if available to generate a random number in an interval .
95
- # Lemire's algorithm has improved performance when {max}+1 is not a power of two.
113
+ if use_masked : # Use masking & rejection.
114
+ command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint{bits}, use_masked=True)'
115
+ else : # Use Lemire's algo .
116
+ command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint{bits}, use_masked=False)'
96
117
97
- if use_masked :
98
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint8, use_masked=True)' # Use masking & rejection.
99
- else :
100
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint8, use_masked=False)' # Use Lemire's algo.
118
+ command = command .format (min = minimum , max = max , bits = bits )
101
119
102
- command = command .format (min = min , max = max )
103
-
104
- command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint8)'
105
- command_numpy = command_numpy .format (min = min , max = max )
120
+ command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint{bits})'
121
+ command_numpy = command_numpy .format (min = minimum , max = max , bits = bits )
106
122
107
123
run_timer (dist , command , command_numpy , SETUP ,
108
- '8-bit bounded unsigned integers (max={max}, use_masked={use_masked})' .format (max = max , use_masked = use_masked ))
109
-
110
-
111
- def timer_16bit_bounded (max = 1535 , use_masked = True ):
112
- min = 0
113
-
114
- dist = 'random_uintegers'
115
-
116
- # Note on performance of generating random numbers in an interval:
117
- # use_masked=True : masking and rejection sampling is used to generate a random number in an interval.
118
- # use_masked=False : Lemire's algorithm is used if available to generate a random number in an interval.
119
- # Lemire's algorithm has improved performance when {max}+1 is not a power of two.
120
-
121
- if use_masked :
122
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint16, use_masked=True)' # Use masking & rejection.
123
- else :
124
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint16, use_masked=False)' # Use Lemire's algo.
125
-
126
- command = command .format (min = min , max = max )
127
-
128
- command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint16)'
129
- command_numpy = command_numpy .format (min = min , max = max )
130
-
131
- run_timer (dist , command , command_numpy , SETUP ,
132
- '16-bit bounded unsigned integers (max={max}, use_masked={use_masked})' .format (max = max , use_masked = use_masked ))
124
+ '{bits}-bit bounded unsigned integers (max={max}, '
125
+ 'use_masked={use_masked})' .format (max = max , use_masked = use_masked , bits = bits ))
133
126
134
127
135
128
def timer_32bit ():
136
129
info = np .iinfo (np .uint32 )
137
- min , max = info .min , info .max
130
+ minimum , maximum = info .min , info .max
138
131
dist = 'random_uintegers'
139
132
command = 'rg.random_uintegers(1000000, 32)'
140
133
command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint32)'
141
- command_numpy = command_numpy .format (min = min , max = max )
134
+ command_numpy = command_numpy .format (min = minimum , max = maximum )
142
135
run_timer (dist , command , command_numpy , SETUP , '32-bit unsigned integers' )
143
136
144
137
145
- def timer_32bit_bounded (max = 1535 , use_masked = True ):
146
- min = 0
147
-
148
- dist = 'random_uintegers'
149
-
150
- # Note on performance of generating random numbers in an interval:
151
- # use_masked=True : masking and rejection sampling is used to generate a random number in an interval.
152
- # use_masked=False : Lemire's algorithm is used if available to generate a random number in an interval.
153
- # Lemire's algorithm has improved performance when {max}+1 is not a power of two.
154
-
155
- if use_masked :
156
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint32, use_masked=True)' # Use masking & rejection.
157
- else :
158
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint32, use_masked=False)' # Use Lemire's algo.
159
-
160
- command = command .format (min = min , max = max )
161
-
162
- command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint32)'
163
- command_numpy = command_numpy .format (min = min , max = max )
164
-
165
- run_timer (dist , command , command_numpy , SETUP ,
166
- '32-bit bounded unsigned integers (max={max}, use_masked={use_masked})' .format (max = max , use_masked = use_masked ))
167
-
168
-
169
138
def timer_64bit ():
170
139
info = np .iinfo (np .uint64 )
171
- min , max = info .min , info .max
140
+ minimum , maximum = info .min , info .max
172
141
dist = 'random_uintegers'
173
142
command = 'rg.random_uintegers(1000000)'
174
143
command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint64)'
175
- command_numpy = command_numpy .format (min = min , max = max )
144
+ command_numpy = command_numpy .format (min = minimum , max = maximum )
176
145
run_timer (dist , command , command_numpy , SETUP , '64-bit unsigned integers' )
177
146
178
147
179
- def timer_64bit_bounded (max = 1535 , use_masked = True ):
180
- min = 0
181
-
182
- dist = 'random_uintegers'
183
-
184
- # Note on performance of generating random numbers in an interval:
185
- # use_masked=True : masking and rejection sampling is used to generate a random number in an interval.
186
- # use_masked=False : Lemire's algorithm is used if available to generate a random number in an interval.
187
- # Lemire's algorithm has improved performance when {max}+1 is not a power of two.
188
-
189
- if use_masked :
190
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint64, use_masked=True)' # Use masking & rejection.
191
- else :
192
- command = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint64, use_masked=False)' # Use Lemire's algo.
193
-
194
- command = command .format (min = min , max = max )
195
-
196
- command_numpy = 'rg.randint({min}, {max}+1, 1000000, dtype=np.uint64)'
197
- command_numpy = command_numpy .format (min = min , max = max )
198
-
199
- run_timer (dist , command , command_numpy , SETUP ,
200
- '64-bit bounded unsigned integers (max={max}, use_masked={use_masked})' .format (max = max , use_masked = use_masked ))
201
-
202
-
203
148
def timer_normal_zig ():
204
149
dist = 'standard_normal'
205
150
command = 'rg.standard_normal(1000000)'
@@ -210,35 +155,47 @@ def timer_normal_zig():
210
155
211
156
if __name__ == '__main__' :
212
157
import argparse
158
+
213
159
parser = argparse .ArgumentParser ()
214
- parser .add_argument ('--full' , dest = 'full' , action = 'store_true' )
160
+ parser .add_argument ('-f' , '--full' ,
161
+ help = 'Run benchmarks for a wide range of distributions.'
162
+ ' If not provided, only tests the production of '
163
+ 'uniform values.' ,
164
+ dest = 'full' , action = 'store_true' )
165
+ parser .add_argument ('-bi' , '--bounded-ints' ,
166
+ help = 'Included benchmark coverage of the bounded '
167
+ 'integer generators in a full run.' ,
168
+ dest = 'bounded_ints' , action = 'store_true' )
215
169
args = parser .parse_args ()
216
170
217
171
timer_uniform ()
218
172
if args .full :
219
173
timer_raw ()
220
- timer_8bit_bounded (use_masked = True )
221
- timer_8bit_bounded (max = 64 , use_masked = False ) # Worst case for Numpy.
222
- timer_8bit_bounded (max = 95 , use_masked = False ) # Typ. avrg. case for Numpy.
223
- timer_8bit_bounded (max = 127 , use_masked = False ) # Best case for Numpy.
174
+ if args .bounded_ints :
175
+ timer_bounded (use_masked = True )
176
+ timer_bounded (max = 64 , use_masked = False ) # Worst case for Numpy.
177
+ timer_bounded (max = 95 , use_masked = False ) # Typ. avrg. case for Numpy.
178
+ timer_bounded (max = 127 , use_masked = False ) # Best case for Numpy.
224
179
225
- timer_16bit_bounded ( use_masked = True )
226
- timer_16bit_bounded ( max = 1024 , use_masked = False ) # Worst case for Numpy.
227
- timer_16bit_bounded ( max = 1535 , use_masked = False ) # Typ. avrg. case for Numpy.
228
- timer_16bit_bounded ( max = 2047 , use_masked = False ) # Best case for Numpy.
180
+ timer_bounded ( 16 , use_masked = True )
181
+ timer_bounded ( 16 , max = 1024 , use_masked = False ) # Worst case for Numpy.
182
+ timer_bounded ( 16 , max = 1535 , use_masked = False ) # Typ. avrg. case for Numpy.
183
+ timer_bounded ( 16 , max = 2047 , use_masked = False ) # Best case for Numpy.
229
184
230
185
timer_32bit ()
231
186
232
- timer_32bit_bounded (use_masked = True )
233
- timer_32bit_bounded (max = 1024 , use_masked = False ) # Worst case for Numpy.
234
- timer_32bit_bounded (max = 1535 , use_masked = False ) # Typ. avrg. case for Numpy.
235
- timer_32bit_bounded (max = 2047 , use_masked = False ) # Best case for Numpy.
187
+ if args .bounded_ints :
188
+ timer_bounded (32 , use_masked = True )
189
+ timer_bounded (32 , max = 1024 , use_masked = False ) # Worst case for Numpy.
190
+ timer_bounded (32 , max = 1535 , use_masked = False ) # Typ. avrg. case for Numpy.
191
+ timer_bounded (32 , max = 2047 , use_masked = False ) # Best case for Numpy.
236
192
237
193
timer_64bit ()
238
194
239
- timer_64bit_bounded (use_masked = True )
240
- timer_64bit_bounded (max = 1024 , use_masked = False ) # Worst case for Numpy.
241
- timer_64bit_bounded (max = 1535 , use_masked = False ) # Typ. avrg. case for Numpy.
242
- timer_64bit_bounded (max = 2047 , use_masked = False ) # Best case for Numpy.
195
+ if args .bounded_ints :
196
+ timer_bounded (64 , use_masked = True )
197
+ timer_bounded (64 , max = 1024 , use_masked = False ) # Worst case for Numpy.
198
+ timer_bounded (64 , max = 1535 , use_masked = False ) # Typ. avrg. case for Numpy.
199
+ timer_bounded (64 , max = 2047 , use_masked = False ) # Best case for Numpy.
243
200
244
201
timer_normal_zig ()
0 commit comments