Fix performance issues when creating multiple instances of Period (#12903, #11831)
State: closed

closes #12903
closes #11831  
- [x] tests added / passed
- [x] passes `git diff upstream/master | flake8 --diff`
- [x] whatsnew entry


Labels:
name: Performance
description: Memory or execution speed performance
name: Period
description: Period data type

Comments:
pls run the asv suite for relevant benchmarks

needs a whatsnew entry 

also pls show the asv runs for the period benchmarks

@jreback , @tswicegood Is there a doc describing the hoops I need to jump through to get Travis and Jeff happy to merge? :smile: I.e. the names of the scripts I need to run to add asv benchmarks, pass coverage and pep8 requirements?

@rs2 see @jreback's previous comments:
- add a note in the whatsnew file about the performance improvement (doc/source/whatsnew/v0.18.1)
- run the asv benchmarks and paste the results here, see http://pandas-docs.github.io/pandas-docs-travis/contributing.html#running-the-performance-test-suite (you can select the relevant ones to run, related to periods and timeseries plotting)
- for travis, you just have a failing test for which you need to fix the code, it seems related to the moving of the constants.

can you show some benchmark results (prob need some asv's for this as well).

Will submit another pull request

just force push to this PR
opening multiple PRs for the same issue is confusing and more work for others

The [failing test](https://travis-ci.org/pydata/pandas/jobs/125805786) is not mine.

@rs2 that test test runner has been known failing for a while.

## [Current coverage](https://codecov.io/gh/pydata/pandas/pull/12909?src=pr) is **83.84%**

> Merging [#12909](https://codecov.io/gh/pydata/pandas/pull/12909?src=pr) into [master](https://codecov.io/gh/pydata/pandas/branch/master?src=pr) will increase coverage by **+0.10%**

``` diff
@@           master     #12909   diff @@
========================================
  Files         134        136     +2   
  Lines       49565      49716   +151   
  Methods         0          0          
  Branches        0          0          
========================================
+ Hits        41507      41684   +177   
+ Misses       8058       8032    -26   
  Partials        0          0          
```
1. 6 files in `pandas/tseries` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/5cbe9f77c808a5bd5b3dc7b02a0fece4c88044fd/changes?src=pr#70616E6461732F74736572696573) 
   - Misses `+4` 
   - Hits `+3`
2. 2 files in `pandas/tools` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/5cbe9f77c808a5bd5b3dc7b02a0fece4c88044fd/changes?src=pr#70616E6461732F746F6F6C73) 
   - Misses `+1` 
   - Hits `+53`
3. 2 files in `pandas/core` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/5cbe9f77c808a5bd5b3dc7b02a0fece4c88044fd/changes?src=pr#70616E6461732F636F7265) 
   - Misses `+2` 
   - Hits `-2`
4. 4 files in `pandas` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/5cbe9f77c808a5bd5b3dc7b02a0fece4c88044fd/changes?src=pr#70616E646173) 
   - Misses `+2` 
   - Hits `+8`
5. 2 files (not in diff) in `pandas` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/5cbe9f77c808a5bd5b3dc7b02a0fece4c88044fd/changes?src=pr#70616E646173) 
   - Misses `-7` 
   - Hits `+7`

[![Sunburst](https://codecov.io/gh/pydata/pandas/pull/12909/graphs/sunburst.svg?src=pr&size=660)](https://codecov.io/gh/pydata/pandas/pull/12909?src=pr)

> Powered by [Codecov](https://codecov.io?src=pr). Last updated by 5cbe9f7

Adding `asv` benchmarks...

### `asv` benchmarks

From 5.89s to 525ms:

#### Before the change:

```
~/pandas_master/asv_bench$ asv dev -b create_period
· Discovering benchmarks
· Running 1 total benchmarks (1 commits * 1 environments * 1 benchmarks)
[  0.00%] ·· Building for /home/pashok/anaconda3/bin/python
[  0.00%] ·· Benchmarking /home/pashok/anaconda3/bin/python
[100.00%] ··· Running period.create_period_index_from_date_range.time_period_index                                                                                                    5.89s
```

#### After the change

```
~/pandas/asv_bench$ asv dev -b create_period
· Discovering benchmarks
· Running 1 total benchmarks (1 commits * 1 environments * 1 benchmarks)
[  0.00%] ·· Building for /home/pashok/anaconda3/bin/python
[  0.00%] ·· Benchmarking /home/pashok/anaconda3/bin/python
[100.00%] ··· Running period.create_period_index_from_date_range.time_period_index                                                                                   525.84ms
```

Nice speedup! Did you run the benchmarks on py2 or py3?

`~/pandas/asv_bench$ asv continuous -b period` (`-b` just matches so you can see results (will compare)

@jorisvandenbossche : plot `asv` benchmarks:

#### Before the change

```
~/pandas_master/asv_bench$ asv dev -b foo
· Discovering benchmarks
· Running 2 total benchmarks (1 commits * 1 environments * 2 benchmarks)
[  0.00%] ·· Building for /home/pashok/anaconda3/bin/python
[  0.00%] ·· Benchmarking /home/pashok/anaconda3/bin/python
[ 50.00%] ··· Running foo_bar.test_foo_bar.time_plot_date_ranged_df                                                                                                                   1.81s
[100.00%] ··· Running foo_bar.test_foo_bar.time_plot_plain_df                                                                                                                      129.33ms
~/pandas_master/asv_bench$ python --version
Python 3.5.1 :: Anaconda 2.5.0 (64-bit)
~/pandas_master/asv_bench$
```

#### After the change

```
~/pandas/asv_bench$ asv dev -b foo
· Discovering benchmarks
· Running 2 total benchmarks (1 commits * 1 environments * 2 benchmarks)
[  0.00%] ·· Building for /home/pashok/anaconda3/bin/python
[  0.00%] ·· Benchmarking /home/pashok/anaconda3/bin/python
[ 50.00%] ··· Running foo_bar.test_foo_bar.time_plot_date_ranged_df                                                                                                  214.24ms
[100.00%] ··· Running foo_bar.test_foo_bar.time_plot_plain_df                                                                                                        123.06ms
~/pandas/asv_bench$ python --version
Python 3.5.1 :: Anaconda 2.5.0 (64-bit)
~/pandas/asv_bench$
```

``` python
import numpy as np
import pandas as pd


class test_foo_bar(object):

    goal_time = 0.2
    N = 2000

    def setup(self):
        self.date_ranged_df = pd.DataFrame(np.random.randn(self.N, 5), index=pd.date_range('1/1/1975', periods=self.N))
        self.plain_df = pd.DataFrame(np.random.randn(self.N, 5))

    def time_plot_date_ranged_df(self):
        self.date_ranged_df.plot()

    def time_plot_plain_df(self):
        self.plain_df.plot()
```

Anything else needs to be done to be able to merge?

looks good. ping when green.

thanks @rs2 

This was a big TODO I had when moving Period to Cython. Thank you for working it out @rs2.