Browse code

Merge branch 'asv' into 'master'

implement benchmarks with asv

See merge request qt/adaptive!24

Bas Nijholt authored on 16/11/2017 16:36:43
Showing 6 changed files
... ...
@@ -87,3 +87,11 @@ ENV/
87 87
 
88 88
 # Rope project settings
89 89
 .ropeproject
90
+
91
+# MacOS files
92
+*.DS_Store
93
+
94
+# asv files
95
+benchmarks/html/
96
+benchmarks/results/
97
+.asv
90 98
\ No newline at end of file
... ...
@@ -1,4 +1,5 @@
1 1
 # Tools for adaptive parallel evaluation of functions
2
+[![asv](http://img.shields.io/badge/benchmarked%20by-asv-green.svg?style=flat)](https://gitlab.kwant-project.org/qt/adaptive/)
2 3
 
3 4
 ## Development
4 5
 
5 6
new file mode 100644
... ...
@@ -0,0 +1,44 @@
1
+# adaptive benchmarks
2
+
3
+Benchmarking adaptive with Airspeed Velocity.
4
+
5
+## Usage
6
+
7
+Airspeed Velocity manages building and Python conda environments by itself,
8
+unless told otherwise. To run the benchmarks, you do not need to install a
9
+development version of adaptive to your current Python environment.
10
+
11
+Run ASV commands (record results and generate HTML):
12
+
13
+```bash
14
+cd benchmarks
15
+asv run --skip-existing-commits --steps 10 ALL
16
+asv publish
17
+asv preview
18
+```
19
+
20
+More on how to use ``asv`` can be found in `ASV documentation`_
21
+Command-line help is available as usual via ``asv --help`` and
22
+``asv run --help``.
23
+
24
+
25
+## Writing benchmarks
26
+
27
+See [`ASV documentation`](https://asv.readthedocs.io/) for basics on how to write benchmarks.
28
+
29
+Some things to consider:
30
+
31
+- The benchmark suite should be importable with any adaptive version.
32
+
33
+- The benchmark parameters etc. should not depend on which adaptive version
34
+  is installed.
35
+
36
+- Try to keep the runtime of the benchmark reasonable.
37
+
38
+- Prefer ASV's ``time_`` methods for benchmarking times rather than cooking up
39
+  time measurements via ``time.clock``, even if it requires some juggling when
40
+  writing the benchmark.
41
+
42
+- Preparing arrays etc. should generally be put in the ``setup`` method rather
43
+  than the ``time_`` methods, to avoid counting preparation time together with
44
+  the time of the benchmarked operation.
0 45
new file mode 100644
... ...
@@ -0,0 +1,25 @@
1
+{
2
+    "version": 1,
3
+    "project": "adaptive",
4
+    "project_url": "https://gitlab.kwant-project.org/qt/adaptive",
5
+    "repo": "..",
6
+    "dvcs": "git",
7
+    "environment_type": "conda",
8
+    "install_timeout": 600,
9
+    "show_commit_url": "https://gitlab.kwant-project.org/qt/adaptive/commit/",
10
+    "pythons": ["3.6"],
11
+    "conda_channels": ["conda-forge"],
12
+    "matrix": {
13
+        "numpy": ["1.13"],
14
+        "holoviews": ["1.9.1"],
15
+        "scipy": ["0.19.1"],
16
+        "ipyparallel": ["6.0.2"],
17
+        "sortedcontainers": ["1.5.7"],
18
+    },
19
+    "benchmark_dir": "benchmarks",
20
+    "env_dir": "env",
21
+    "results_dir": "results",
22
+    "html_dir": "html",
23
+    "hash_length": 8,
24
+    "wheel_cache_size": 2
25
+}
0 26
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+
0 2
new file mode 100644
... ...
@@ -0,0 +1,47 @@
1
+import adaptive
2
+
3
+import numpy as np
4
+import random
5
+
6
+
7
+offset = random.uniform(-0.5, 0.5)
8
+
9
+def f_1d(x, offset=offset):
10
+    a = 0.01
11
+    return x + a**2 / (a**2 + (x - offset)**2)
12
+
13
+
14
+def f_2d(xy):
15
+    x, y = xy
16
+    a = 0.2
17
+    return x + np.exp(-(x**2 + y**2 - 0.75**2)**2/a**4)
18
+
19
+
20
+class TimeLearner1D:
21
+    def setup(self):
22
+        self.learner = adaptive.Learner1D(f_1d, bounds=(-1, 1))
23
+
24
+    def time_run(self):
25
+        for _ in range(1000):
26
+            points, _ = self.learner.choose_points(1)
27
+            self.learner.add_data(points, map(f_1d, points))
28
+
29
+
30
+class TimeLearner2D:
31
+    def setup(self):
32
+        self.learner = adaptive.Learner2D(f_2d, bounds=[(-1, 1), (-1, 1)])
33
+        self.xs = np.random.rand(50**2, 2)
34
+        self.ys = np.random.rand(50**2)
35
+
36
+    def time_run(self):
37
+        for _ in range(50**2):
38
+            points, _ = self.learner.choose_points(1)
39
+            self.learner.add_data(points, map(f_2d, points))
40
+
41
+    def time_choose_points(self):
42
+        for _ in range(50**2):
43
+            self.learner.choose_points(1)
44
+
45
+    def time_add_point(self):
46
+        for x, y in zip(self.xs, self.ys):
47
+            self.learner.add_point(x, y)