diff --git a/asv_bench/README.md b/asv_bench/README.md new file mode 100644 index 0000000000..ab9d046f19 --- /dev/null +++ b/asv_bench/README.md @@ -0,0 +1,42 @@ +Benchmarks +========== + +pvlib includes a small number of performance benchmarking tests. These +tests are run using +[airspeed velocity](https://asv.readthedocs.io/en/stable/) (ASV). + +The basic structure of the tests and how to run them is described below. +We refer readers to the ASV documentation for more details. + +The test configuration is described in +[``asv.conf.json``](asv.conf.json). + +The performance tests are located in the [benchmarks](benchmarks) directory. + +First, from this directory, run the tests: + +``` +asv run +``` + +Note that, unlike pytest, the asv tests require changes to be committed +to git before they can be tested. The ``run`` command takes a positional +argument to describe the range of git commits or branches to be tested. +For example, if your feature branch is named ``feature``, a useful asv +run may be: + +``` +asv run master..feature +``` + +Next, publish the test results to the archive: + +``` +asv publish +``` + +Finally, start a http server to view the test results: + +``` +asv preview +``` diff --git a/asv_bench/asv.conf.json b/asv_bench/asv.conf.json new file mode 100644 index 0000000000..ec7050a41b --- /dev/null +++ b/asv_bench/asv.conf.json @@ -0,0 +1,147 @@ +{ + // The version of the config file format. Do not change, unless + // you know what you are doing. + "version": 1, + + // The name of the project being benchmarked + "project": "pvlib python", + + // The project's homepage + "project_url": "https://github.com/pvlib/pvlib-python", + + // The URL or local path of the source code repository for the + // project being benchmarked + "repo": "..", + + // List of branches to benchmark. If not provided, defaults to "master" + // (for git) or "default" (for mercurial). + // "branches": ["master"], // for git + // "branches": ["default"], // for mercurial + + // The DVCS being used. If not set, it will be automatically + // determined from "repo" by looking at the protocol in the URL + // (if remote), or by looking for special directories, such as + // ".git" (if local). + "dvcs": "git", + + // The tool to use to create environments. May be "conda", + // "virtualenv" or other value depending on the plugins in use. + // If missing or the empty string, the tool will be automatically + // determined by looking for tools on the PATH environment + // variable. + "environment_type": "conda", + + // timeout in seconds for installing any dependencies in environment + // defaults to 10 min + //"install_timeout": 600, + + // the base URL to show a commit for the project. + // "show_commit_url": "http://github.com/pvlib/pvlib-python/commit/", + + // The Pythons you'd like to test against. If not provided, defaults + // to the current version of Python used to run `asv`. + // "pythons": ["2.7", "3.7"], + + // The matrix of dependencies to test. Each key is the name of a + // package (in PyPI) and the values are version numbers. An empty + // list or empty string indicates to just test against the default + // (latest) version. null indicates that the package is to not be + // installed. If the package to be tested is only available from + // PyPi, and the 'environment_type' is conda, then you can preface + // the package name by 'pip+', and the package will be installed via + // pip (with all the conda available packages installed first, + // followed by the pip installed packages). + // + // "matrix": { + // "numpy": ["1.6", "1.7"], + // "six": ["", null], // test with and without six installed + // "pip+emcee": [""], // emcee is only available for install with pip. + // }, + "matrix": { + "numpy": [""], + "pandas": [""], + "bottleneck": [""], + "numexpr": [""] + }, + + // Combinations of libraries/python versions can be excluded/included + // from the set to test. Each entry is a dictionary containing additional + // key-value pairs to include/exclude. + // + // An exclude entry excludes entries where all values match. The + // values are regexps that should match the whole string. + // + // An include entry adds an environment. Only the packages listed + // are installed. The 'python' key is required. The exclude rules + // do not apply to includes. + // + // In addition to package names, the following keys are available: + // + // - python + // Python version, as in the *pythons* variable above. + // - environment_type + // Environment type, as above. + // - sys_platform + // Platform, as in sys.platform. Possible values for the common + // cases: 'linux2', 'win32', 'cygwin', 'darwin'. + // + // "exclude": [ + // {"python": "3.2", "sys_platform": "win32"}, // skip py3.2 on windows + // {"environment_type": "conda", "six": null}, // don't run without six on conda + // ], + // + // "include": [ + // // additional env for python2.7 + // {"python": "2.7", "numpy": "1.8"}, + // // additional env if run on windows+conda + // {"platform": "win32", "environment_type": "conda", "python": "2.7", "libpython": ""}, + // ], + + // The directory (relative to the current directory) that benchmarks are + // stored in. If not provided, defaults to "benchmarks" + "benchmark_dir": "benchmarks", + + // The directory (relative to the current directory) to cache the Python + // environments in. If not provided, defaults to "env" + "env_dir": ".asv/env", + + // The directory (relative to the current directory) that raw benchmark + // results are stored in. If not provided, defaults to "results". + "results_dir": ".asv/results", + + // The directory (relative to the current directory) that the html tree + // should be written to. If not provided, defaults to "html". + "html_dir": ".asv/html", + + // The number of characters to retain in the commit hashes. + // "hash_length": 8, + + // `asv` will cache wheels of the recent builds in each + // environment, making them faster to install next time. This is + // number of builds to keep, per environment. + // "wheel_cache_size": 0 + + // The commits after which the regression search in `asv publish` + // should start looking for regressions. Dictionary whose keys are + // regexps matching to benchmark names, and values corresponding to + // the commit (exclusive) after which to start looking for + // regressions. The default is to start from the first commit + // with results. If the commit is `null`, regression detection is + // skipped for the matching benchmark. + // + // "regressions_first_commits": { + // "some_benchmark": "352cdf", // Consider regressions only after this commit + // "another_benchmark": null, // Skip regression detection altogether + // } + + // The thresholds for relative change in results, after which `asv + // publish` starts reporting regressions. Dictionary of the same + // form as in ``regressions_first_commits``, with values + // indicating the thresholds. If multiple entries match, the + // maximum is taken. If no entry matches, the default is 5%. + // + // "regressions_thresholds": { + // "some_benchmark": 0.01, // Threshold of 1% + // "another_benchmark": 0.5, // Threshold of 50% + // } +} diff --git a/asv_bench/benchmarks/__init__.py b/asv_bench/benchmarks/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/asv_bench/benchmarks/__init__.py @@ -0,0 +1 @@ + diff --git a/asv_bench/benchmarks/location.py b/asv_bench/benchmarks/location.py new file mode 100644 index 0000000000..7d3de6023f --- /dev/null +++ b/asv_bench/benchmarks/location.py @@ -0,0 +1,20 @@ +# Write the benchmarking functions here. +# See "Writing benchmarks" in the asv docs for more information. + +import pandas as pd +import pvlib + +class TimeSuite: + """ + An example benchmark that times the performance of various kinds + of iterating over dictionaries in Python. + """ + def setup(self): + self.location = pvlib.location.Location(32, -110, altitude=700) + self.times = pd.DatetimeIndex(start='20180601', freq='3min', + periods=1440) + self.solar_position = self.location.get_solarposition(self.times) + + # GH 502 + def time_location_get_airmass(self): + self.location.get_airmass(solar_position=self.solar_position) diff --git a/asv_bench/benchmarks/solarposition.py b/asv_bench/benchmarks/solarposition.py new file mode 100644 index 0000000000..c65397fb00 --- /dev/null +++ b/asv_bench/benchmarks/solarposition.py @@ -0,0 +1,23 @@ +# Write the benchmarking functions here. +# See "Writing benchmarks" in the asv docs for more information. + +import pandas as pd +import pvlib + +class TimeSuite: + """ + An example benchmark that times the performance of various kinds + of iterating over dictionaries in Python. + """ + def setup(self): + self.times = pd.DatetimeIndex(start='20180601', freq='1min', + periods=14400) + self.times_localized = self.times.tz_localize('Etc/GMT+7') + + # GH 512 + def time_ephemeris(self): + pvlib.solarposition.ephemeris(self.times, 35.1, -106.6) + + # GH 512 + def time_ephemeris_localized(self): + pvlib.solarposition.ephemeris(self.times_localized, 35.1, -106.6) diff --git a/docs/sphinx/source/contributing.rst b/docs/sphinx/source/contributing.rst index 2819a20248..d6407252ce 100644 --- a/docs/sphinx/source/contributing.rst +++ b/docs/sphinx/source/contributing.rst @@ -404,6 +404,17 @@ PVSystem method is called through ``ModelChain.run_model``. assert isinstance(mc.dc, (pd.Series, pd.DataFrame)) +Benchmarking +~~~~~~~~~~~~ + +pvlib includes a small number of performance benchmarking tests. These +tests are run using the `airspeed velocity +`_ tool. We do not require new +performance tests for most contributions at this time. Pull request +reviewers will provide further information if a performance test is +necessary. + + This documentation ~~~~~~~~~~~~~~~~~~ diff --git a/docs/sphinx/source/whatsnew/v0.6.0.rst b/docs/sphinx/source/whatsnew/v0.6.0.rst index dc50a50d79..58ec58e738 100644 --- a/docs/sphinx/source/whatsnew/v0.6.0.rst +++ b/docs/sphinx/source/whatsnew/v0.6.0.rst @@ -100,6 +100,8 @@ Testing * Use pytest-mock to ensure that ModelChain DC model is set up correctly. * Add Python 3.7 to build matrix * Make test_forecast.py more robust. (:issue:`293`) +* Add airspeed velocity performance testing configuration and a few tests. + (:issue:`419`) Contributors