Skip to content

Commit 905a141

Browse files
committed
Add numpy performance tests
1 parent 26830d8 commit 905a141

File tree

3 files changed

+518
-2
lines changed

3 files changed

+518
-2
lines changed

source-code/numpy-scipy/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ Some examples of numpy and scipy usage. Mainly intended for benchmarking.
44

55
## What is it?
66

7-
1. svd.py`: Python script that reads a dataset representing a matrix in
7+
1. `svd.py`: Python script that reads a dataset representing a matrix in
88
an HDF5 file. It computes the Singular Value Decomposition (SVD) and
99
reconstructs the original matrix from that. Timings for HDF5 reads,
1010
SVD and matrix multiplications are printed.
1111
1. `create_h5.py`: Python script to create an HDF5 file that can be used
1212
by `svd.py`.
13-
1. julia_set.ipynb`: Jupyter notebook to illustrate numpy type conversion.
13+
1. `julia_set.ipynb`: Jupyter notebook to illustrate numpy type conversion.
14+
1. `numpy_performance.ipynb`: Jupyter notebooks illustrating some performance
15+
issues with numpy.
16+
1. `fancy_indexing.py`: Python script that tests performance of fancy indexing
17+
arrays in numpy.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python
2+
#
3+
# This script is intended to benchmark fancy indexiing with respect to
4+
# for loops.
5+
#
6+
# It takes the following commannd line arguments:
7+
# * --n: the numer of rows/columns in the matrix
8+
# * --r: the number of repetitions
9+
# * --algo: the algorithm(s) to use (either 'iterative' or 'fancy', or both)
10+
# This option can be specified multiple times, once for each of
11+
# the algorithms to use.
12+
# For each repetition, the algorithm is timed to microsecond precision.
13+
# For each repetition, the following values are printed to standard output:
14+
# * the name of the algorithm
15+
# * the number of rows/columns in the matrix
16+
# * the number of the repetition
17+
# * the time it took to run the algorithm, in microseconds.
18+
# When all repetitions are done, the following values are printed to standard
19+
# output:
20+
# * the name of the algorithm
21+
# * the number of rows/columns in the matrix
22+
# * the number of repetitions
23+
# * the average time it took to run the algorithm, in microseconds.
24+
# * the standard deviation of the time it took to run the algorithm, in
25+
# microseconds.
26+
# * the factor by which the value for the algorithm is slower than the
27+
# fastest algorithm.
28+
#
29+
# -----------------------------------------------------------------------------
30+
31+
import argparse
32+
from collections import defaultdict
33+
import numpy as np
34+
import timeit
35+
36+
37+
def setup(n):
38+
A = np.random.uniform(-1.0, 1.0, size=(n, n))
39+
B = np.random.uniform(-1.0, 1.0, size=A.shape)
40+
return A, B
41+
42+
def flip_signs_iterative(A, B):
43+
for i in range(A.shape[0]):
44+
for j in range(A.shape[1]):
45+
if B[i, j] > 0.5:
46+
A[i, j] *= -A[i, j]
47+
48+
def flip_signs_fancy(A, B):
49+
A[B > 0.5] *= -A[B > 0.5]
50+
51+
def main():
52+
parser = argparse.ArgumentParser()
53+
parser.add_argument('--n', type=int, default=100,
54+
help='number of rows/columns in the matrix (default: 100')
55+
parser.add_argument('--r', type=int, default=1,
56+
help='number of repetitions (default: 1')
57+
parser.add_argument('--algo', action='append', default=[],
58+
choices=['iterative', 'fancy'],
59+
help='algorithm(s) to use (default: none)')
60+
args = parser.parse_args()
61+
62+
algorithms_lib = {
63+
'iterative': flip_signs_iterative,
64+
'fancy': flip_signs_fancy,
65+
}
66+
algorithms = [algorithms_lib[algo] for algo in args.algo]
67+
68+
timings = defaultdict(list)
69+
print('algorithm,n,repetition,time')
70+
for i in range(1, args.r + 1):
71+
for algo in algorithms:
72+
A, B = setup(args.n)
73+
timings[algo].append(timeit.timeit(lambda: algo(A, B), number=1))
74+
print(f'{algo.__name__},{args.n},{i},{timings[algo][-1]:.6f}')
75+
print('summary:')
76+
min_time = min([np.mean(timings[algo]) for algo in algorithms])
77+
print(' algorithm,n,repetitions,mean,std,relative')
78+
for algo in algorithms:
79+
print(f' {algo.__name__},{args.n},{args.r},{np.mean(timings[algo]):.6f},{np.std(timings[algo]):.6f},{np.mean(timings[algo]) / min_time:.2f}')
80+
81+
if __name__ == '__main__':
82+
main()

0 commit comments

Comments
 (0)