Move frequencies functions to cython
State: closed

Move some more functions from `tseries.frequencies` up to `tslibs.frequencies`, update imports in `_libs.period` to cimports

- [x] closes #xxxx
- [ ] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Labels:
name: Frequency
description: DateOffsets
name: Clean

Comments:
The travis error is a flake8 complaint that `get_freq` is getting redefined in `tseries.frequencies`.  AFAICT it is confused about scopes, because the original `get_freq` is a function imported at the module level and the other places `get_freq` is defined are both methods.
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=h1) Report
> Merging [#17746](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/4a8496b2bf02df521b6b7f15843c515545a3d192?src=pr&el=desc) will **decrease** coverage by `0.02%`.
> The diff coverage is `92.3%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/17746/graphs/tree.svg?height=150&width=650&token=eZ4WkYLtcO&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #17746      +/-   ##
==========================================
- Coverage   91.54%   91.51%   -0.03%     
==========================================
  Files         148      148              
  Lines       48804    48680     -124     
==========================================
- Hits        44676    44550     -126     
- Misses       4128     4130       +2
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.88% <92.3%> (-0.03%)` | :arrow_down: |
| #single | `41.68% <53.84%> (+0.05%)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/tseries/frequencies.py](https://codecov.io/gh/pandas-dev/pandas/pull/17746/diff?src=pr&el=tree#diff-cGFuZGFzL3RzZXJpZXMvZnJlcXVlbmNpZXMucHk=) | `95.9% <92.3%> (+1.99%)` | :arrow_up: |
| [pandas/plotting/\_converter.py](https://codecov.io/gh/pandas-dev/pandas/pull/17746/diff?src=pr&el=tree#diff-cGFuZGFzL3Bsb3R0aW5nL19jb252ZXJ0ZXIucHk=) | `65.22% <0%> (-1.74%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=footer). Last update [4a8496b...8129b1c](https://codecov.io/gh/pandas-dev/pandas/pull/17746?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Is the flake8 warning a deal-breaker?
Please unsubscribe me

On Tue, Oct 17, 2017 at 3:35 PM, jbrockmendel <notifications@github.com>
wrote:

> Is the flake8 warning a deal-breaker?
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/pandas-dev/pandas/pull/17746#issuecomment-337345506>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAJfa71N9T-MR_GNPgFhntVj9U0YQIkSks5stQF2gaJpZM4Pq-NZ>
> .
>



-- 
Greg Gurevich
greggurevich@gmail.com
cell: 1-917-504-7105

needs a rebase
Travis error was an ImportError for moto.  Rebase and push...
Bit of a crunch this morning, so doing old-style merging instead of rebasing.  Don't worry, I do plan to change this habit.
> Bit of a crunch this morning, so doing old-style merging instead of rebasing. Don't worry, I do plan to change this habit.

Please don't. Merging is just easier to do, makes it easier to see what changed and to keep track of reviews, doesn't destroy links ...


@jbrockmendel Can you give an idea of the speed-up of moving this to cython?
> Please don't. Merging is just easier to do, makes it easier to see what changed and to keep track of reviews, doesn't destroy links ...

@jreback now I'm confused.  Yesterday I thought you were encouraging me to use "git rebase upstream/master" instead of "git pull upstream master".  The latter is what I've been doing all along (and did this morning).

<b>update</b> Woops, I assumed that the referenced comment was from jreback, didn't notice it was from @jorisvandenbossche.  No longer confused.
> Can you give an idea of the speed-up of moving this to cython?

@jorisvandenbossche I'll run asv and post.  On its own I expect this to be pretty minor, as there is very little typing.  The endgame is getting `to_offset` into cython, thereby getting non-cython out of tslib and period.
> @jreback now I'm confused. Yesterday I thought you were encouraging me to use "git rebase upstream/master" instead of "git pull upstream master"

We just differ from opinion :-) I just mailed to open it as a broader discussion: https://mail.python.org/pipermail/pandas-dev/2017-November/000632.html (btw, if you are not yet subscribed to that list, you should do that, it has currently not much traffic though)
> On its own I expect this to be pretty minor, as there is very little typing. The endgame is getting to_offset into cython, thereby getting non-cython out of tslib and period.

Note that just moving things to cython does not necessarily help in moving to_offset to cython / improving its performance. It's not possible to directly do a PR to cythonize to_offset? (and then cythonize those parts that are needed by it) So we can see the actual benefit of doing that? 
As IMO we should not move things to cython if it has no clear benefit (as it has drawbacks!)

(note that I didn't follow all of your PRs, so there might be a good reason. But for that, it is always good to give some more context in the top post of PRs)
>  It's not possible to directly do a PR to cythonize to_offset?

Not if we want to keep the `tslibs` dependency graph DAG, which I very much do.  One of the first things I noticed when I got started here is a note in `_libs.__init__` that left an impression:

```
# TODO
# period is directly dependent on tslib and imports python
# modules, so exposing Period as an alias is currently not possible
# from period import Period
```

Getting `to_offset` into cython in a meaningful way means getting its dependencies there first.  In particular, making `DateOffset` and its subclasses immutable is the big outstanding hurdle that will get us _big_ perf boost.  (The sticking point there is that making `DateOffset` a cython class is causing pickle test errors #18224).

> As IMO we should not move things to cython if it has no clear benefit (as it has drawbacks!)

That's fair.  Working pretty specifically in this corner of the code it is easy to get caught up in it.  It wouldn't be the first time I feel prey to "we can put all the timedelta stuff in the same place!" (fortunately cooler heads prevailed in #18194).  In this case we're talking about dependencies of functions that _definitely_ belong in cython.

I'll be happy to go into more detail on the thought process and/or the perf hotspots if you want.

BTW after this, `tseries.offsets` is getting a lot of attention (#18263) but `tseries.frequencies` is getting left alone at least until that pickle issue is resolved.
This has been sitting on the back-burner for a while, somehow hasn't amassed any merge conflicts.

ATM _libs.period calls into tseries.frequencies in 5 places.  This moves 3 of those into libfreqs.
HTTPError 502, will re-push this evening.
The followup to ccalendar will have nonzero overlap with this.  If we can get this in first we can avoid a rebase cycle.
Plotting error in app egos looks unrelated
also pls run/show an asv.
<b>Update</b> The asvs posted below are against an out-of-date master, should be ignored.


On de-privatizing _MONTHS et al, the current plan is to do that at the same time as centralizing those all in ccalendar.  Trying to avoid opening new PRs until current ones are wrapped up (especially #18376),

```
taskset 2 asv continuous -f 1.1 -E virtualenv master HEAD -b timeseries -b period -b timedelta -b timestamp
[...]
[100.00%] ··· Running timestamp.TimestampProperties.time_weekday_name                                                                                                               555.05ns;...    before     after       ratio
  [7495e9ad] [e565a3a5]
+   50.65ms   389.04ms      7.68  timeseries.AsOfDataFrame.time_asof_nan
+   67.04ms   409.69ms      6.11  timeseries.AsOfDataFrame.time_asof
+   81.87μs   463.14μs      5.66  timeseries.AsOfDataFrame.time_asof_single_early
+    6.69ms    31.66ms      4.73  timeseries.DatetimeIndex.time_dti_factorize
+    7.24ms    32.13ms      4.44  timeseries.DatetimeIndex.time_dti_tz_factorize
+    2.38ms     4.74ms      1.99  period.Algorithms.time_drop_duplicates('series')
+    2.86ms     5.20ms      1.81  period.Algorithms.time_value_counts('series')
+    34.37s     48.56s      1.41  gil.nogil_datetime_fields.time_period_to_datetime
+   10.35μs    14.18μs      1.37  offset.YearBegin.time_timeseries_year_incr
+    4.44ms     5.27ms      1.19  timeseries.ResampleSeries.time_timestamp_downsample_mean
+    5.30ms     6.07ms      1.15  timedelta.TimedeltaOps.time_add_td_ts
+  467.33μs   534.28μs      1.14  period.Algorithms.time_value_counts('index')
+   11.89μs    13.54μs      1.14  timestamp.TimestampProperties.time_is_month_start(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+    2.68ms     3.04ms      1.13  timeseries.ResampleDataFrame.time_max_string
+    2.56ms     2.89ms      1.13  timeseries.ResampleDataFrame.time_max_numpy
+    8.05μs     9.07μs      1.13  offset.YearBegin.time_timeseries_year_apply
+     1.46s      1.62s      1.11  timeseries.Iteration.time_iter_periodindex
+    2.57ms     2.83ms      1.10  timeseries.ResampleDataFrame.time_min_string
-   75.25μs    67.93μs      0.90  period.PeriodProperties.time_start_time('M')
-   74.63μs    67.36μs      0.90  period.PeriodUnaryMethods.time_to_timestamp('min')
-   12.47ms    11.24ms      0.90  timeseries.DatetimeIndex.time_infer_freq_none
-   79.79μs    71.82μs      0.90  period.PeriodProperties.time_end_time('min')
-   81.74μs    73.28μs      0.90  period.PeriodProperties.time_end_time('M')
-    7.10μs     6.28μs      0.88  timeseries.DatetimeIndex.time_timestamp_tzinfo_cons
-   11.10μs     9.79μs      0.88  timestamp.TimestampProperties.time_dayofyear(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-  981.14ns   857.63ns      0.87  timestamp.TimestampConstruction.time_parse_iso8601_no_tz
-    8.37μs     7.10μs      0.85  timestamp.TimestampProperties.time_is_month_start(None, 'B')
-    5.48ms     4.49ms      0.82  timeseries.DatetimeAccessor.time_dt_accessor_normalize
-   25.68μs    21.04μs      0.82  period.PeriodUnaryMethods.time_now('M')
-    1.17ms   949.25μs      0.81  binary_ops.Timeseries.time_timestamp_series_compare('US/Eastern')
-    8.85μs     7.11μs      0.80  timestamp.TimestampProperties.time_is_quarter_end(None, 'B')
-    2.00ms     1.47ms      0.73  timeseries.ToDatetime.time_cache_false_with_dup_string_dates_and_format
-  157.02ns   113.39ns      0.72  timedelta.TimedeltaProperties.time_timedelta_days
-  160.52ns   112.39ns      0.70  timedelta.TimedeltaProperties.time_timedelta_microseconds
-    1.27μs   858.47ns      0.67  period.PeriodProperties.time_dayofyear('M')
-  169.56ns   111.04ns      0.65  timedelta.TimedeltaProperties.time_timedelta_seconds
-   18.66ms    11.92ms      0.64  timeseries.AsOfDataFrame.time_asof_single
-  156.93ms    93.58ms      0.60  binary_ops.Timeseries.time_timestamp_ops_diff(None)
-   37.18μs    22.12μs      0.59  period.PeriodUnaryMethods.time_asfreq('M')
-   38.30μs    21.57μs      0.56  period.PeriodUnaryMethods.time_asfreq('min')
-     1.02s   288.29ms      0.28  binary_ops.Timeseries.time_timestamp_ops_diff_with_shift(None)
-  313.48ms    77.47ms      0.25  binary_ops.Timeseries.time_timestamp_ops_diff('US/Eastern')
-  467.71ms    87.34ms      0.19  binary_ops.Timeseries.time_timestamp_ops_diff_with_shift('US/Eastern')
-  130.22ms    17.25ms      0.13  timeseries.DatetimeIndex.time_to_date
-    4.74ms   535.00μs      0.11  timeseries.DatetimeIndex.time_dti_time
-    6.45μs   456.36ns      0.07  timestamp.TimestampProperties.time_is_month_end(None, None)
-    6.05μs   334.01ns      0.06  timestamp.TimestampProperties.time_days_in_month(None, None)
-    6.14μs   335.28ns      0.05  timestamp.TimestampProperties.time_is_year_start(None, None)
-    6.19μs   335.27ns      0.05  timestamp.TimestampProperties.time_is_year_end(None, None)
-    6.01μs   322.71ns      0.05  timestamp.TimestampProperties.time_quarter(None, 'B')
-    6.31μs   334.93ns      0.05  timestamp.TimestampProperties.time_days_in_month(None, 'B')
-    6.18μs   327.88ns      0.05  timestamp.TimestampProperties.time_is_quarter_end(None, None)
-    6.38μs   335.64ns      0.05  timestamp.TimestampProperties.time_is_quarter_start(None, None)
-    6.59μs   333.07ns      0.05  timestamp.TimestampProperties.time_is_leap_year(None, None)
-    6.42μs   323.89ns      0.05  timestamp.TimestampProperties.time_is_month_start(None, None)
-    7.49μs   373.05ns      0.05  timestamp.TimestampProperties.time_week(None, None)
-    7.04μs   318.93ns      0.05  timestamp.TimestampProperties.time_quarter(None, None)
-   13.03μs   459.22ns      0.04  timestamp.TimestampProperties.time_is_month_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   11.06μs   372.30ns      0.03  timestamp.TimestampProperties.time_week(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   10.22μs   331.07ns      0.03  timestamp.TimestampProperties.time_days_in_month(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-   10.71μs   333.88ns      0.03  timestamp.TimestampProperties.time_days_in_month(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   10.73μs   331.22ns      0.03  timestamp.TimestampProperties.time_is_year_start(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   10.65μs   324.90ns      0.03  timestamp.TimestampProperties.time_is_quarter_start(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   10.98μs   325.17ns      0.03  timestamp.TimestampProperties.time_is_month_start(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   11.18μs   329.34ns      0.03  timestamp.TimestampProperties.time_is_quarter_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   11.45μs   328.25ns      0.03  timestamp.TimestampProperties.time_is_year_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   11.81μs   334.09ns      0.03  timestamp.TimestampProperties.time_is_leap_year(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   11.43μs   318.30ns      0.03  timestamp.TimestampProperties.time_quarter(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-   12.59μs   319.85ns      0.03  timestamp.TimestampProperties.time_quarter(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
```

As mentioned elsewhere, `AsOfDataFrame` and `dti_factorize` are at the top of the just-ignore list.  Re-running to double-check on the others.

> On de-privatizing _MONTHS et al, the current plan is

Never-mind, I went and added it to this PR.
asv against an up-to-date master.  Three runs, very little consistency between them.  Appears to be noise.  The only benchmark that shows up as slower in all three runs is `gil.nogil_datetime_fields.time_datetime_to_period`

```
taskset 3 asv continuous -f 1.1 -E virtualenv master HEAD -b timeseries -b period -b timedelta -b timestamp
[...]
   before     after       ratio
  [ae74c2b1] [cb73bd6b]
+   12.28μs    32.54μs      2.65  offset.YearBegin.time_timeseries_year_incr
+  329.49ns   661.68ns      2.01  timestamp.TimestampProperties.time_is_quarter_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
+  328.09ns   633.89ns      1.93  timestamp.TimestampProperties.time_dayofweek(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
+   65.90μs   105.53μs      1.60  period.Indexing.time_series_loc
+   12.59ms    19.50ms      1.55  timeseries.AsOfDataFrame.time_asof_nan_single
+  336.64ns   512.68ns      1.52  timestamp.TimestampProperties.time_days_in_month(None, 'B')
+  307.60ns   466.32ns      1.52  timestamp.TimestampProperties.time_tz(None, None)
+   12.73μs    19.07μs      1.50  timestamp.TimestampProperties.time_is_leap_year(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+   16.76μs    22.33μs      1.33  timeseries.AsOf.time_asof_single_early
+    2.28μs     2.88μs      1.26  timestamp.TimestampConstruction.time_parse_today
+   13.68ms    17.09ms      1.25  timeseries.TimeSeries.time_add_irregular
+    1.09ms     1.36ms      1.25  binary_ops.Timeseries.time_timestamp_series_compare('US/Eastern')
+   10.26μs    12.74μs      1.24  timestamp.TimestampProperties.time_week(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+     1.53s      1.89s      1.23  timeseries.Iteration.time_iter_periodindex
+  118.75ms   146.18ms      1.23  timedelta.ToTimedelta.time_convert_coerce
+  392.03ns   480.49ns      1.23  period.Indexing.time_shape
+  880.61ns     1.05μs      1.19  period.PeriodProperties.time_qyear('min')
+    19.42s     23.00s      1.18  gil.nogil_datetime_fields.time_datetime_to_period
+    2.22ms     2.61ms      1.18  timeseries.ResampleDataFrame.time_mean_numpy
+  453.13ns   530.57ns      1.17  timestamp.TimestampProperties.time_is_month_end(None, None)
+    6.62μs     7.72μs      1.17  timestamp.TimestampProperties.time_dayofyear(None, 'B')
+  437.18ms   507.81ms      1.16  timeseries.Iteration.time_iter_datetimeindex
+    7.14μs     8.25μs      1.16  timestamp.TimestampProperties.time_is_quarter_end(None, 'B')
+    53.99s      1.03m      1.15  gil.nogil_datetime_fields.time_period_to_datetime
+    1.17μs     1.31μs      1.12  timestamp.TimestampProperties.time_offset(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+    5.85μs     6.52μs      1.11  timestamp.TimestampProperties.time_dayofyear(None, None)
-  118.68ns   107.04ns      0.90  timedelta.TimedeltaProperties.time_timedelta_microseconds
-   13.53μs    12.20μs      0.90  timestamp.TimestampProperties.time_is_year_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-    1.29μs     1.16μs      0.90  timestamp.TimestampProperties.time_offset(None, 'B')
-  972.85ns   855.69ns      0.88  period.PeriodProperties.time_daysinmonth('M')
-    5.97ms     5.23ms      0.88  timedelta.TimedeltaOps.time_add_td_ts
-  376.50ns   322.80ns      0.86  timestamp.TimestampProperties.time_dayofweek(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-    1.03μs   880.99ns      0.86  period.PeriodProperties.time_daysinmonth('min')
-    5.05ms     4.29ms      0.85  timeseries.ResampleSeries.time_timestamp_downsample_mean
-   16.31μs    13.73μs      0.84  timestamp.TimestampProperties.time_is_month_start(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-    1.07μs   873.83ns      0.82  period.PeriodProperties.time_month('min')
-  425.35ns   332.84ns      0.78  timestamp.TimestampProperties.time_days_in_month(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-   19.66μs    10.82μs      0.55  timestamp.TimestampProperties.time_dayofyear(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   47.18ms    24.38ms      0.52  period.DataFramePeriodColumn.time_setitem_period_column
-  648.75ns   330.19ns      0.51  timestamp.TimestampProperties.time_is_year_start(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-   23.88ms     7.87ms      0.33  timeseries.DatetimeIndex.time_dti_tz_factorize
-   23.34ms     7.00ms      0.30  timeseries.DatetimeIndex.time_dti_factorize
-  295.00ms    28.71ms      0.10  timeseries.AsOfDataFrame.time_asof
-  317.92ms    29.03ms      0.09  timeseries.AsOfDataFrame.time_asof_nan
```

```
taskset 3 asv continuous -f 1.1 -E virtualenv master HEAD -b timeseries -b period -b timedelta -b timestamp
[...]
   before     after       ratio
  [ae74c2b1] [cb73bd6b]
+   12.56ms    70.35ms      5.60  binary_ops.Timeseries.time_timestamp_ops_diff(None)
+    5.27ms    13.78ms      2.61  timeseries.ResampleSeries.time_timestamp_downsample_mean
+   12.72μs    30.06μs      2.36  timestamp.TimestampProperties.time_is_year_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+   19.10μs    42.25μs      2.21  offset.Day.time_timeseries_day_incr
+    1.45μs     2.96μs      2.04  timestamp.TimestampOps.time_replace_None(None)
+    5.36μs    10.84μs      2.02  timestamp.TimestampAcrossDst.time_replace_across_dst
+    7.13μs     9.23μs      1.30  timestamp.TimestampProperties.time_is_quarter_end(None, 'B')
+    1.03ms     1.24ms      1.21  binary_ops.Timeseries.time_series_timestamp_compare('US/Eastern')
+  533.61μs   606.64μs      1.14  timeseries.DatetimeIndex.time_dti_time
+    7.38μs     8.34μs      1.13  timestamp.TimestampProperties.time_is_month_end(None, 'B')
+    5.77μs     6.53μs      1.13  timestamp.TimestampProperties.time_dayofyear(None, 'B')
+   49.14ms    55.36ms      1.13  timedelta.ToTimedelta.time_convert_string
+  884.33ns   994.40ns      1.12  period.PeriodProperties.time_daysinmonth('M')
+    1.05ms     1.17ms      1.12  binary_ops.Timeseries.time_timestamp_series_compare('US/Eastern')
+    18.76s     21.05s      1.12  gil.nogil_datetime_fields.time_datetime_to_period
-  153.72ms   136.96ms      0.89  timeseries.ToDatetime.time_iso8601_tz_spaceformat
-    1.24ms     1.07ms      0.86  binary_ops.Timeseries.time_timestamp_series_compare(None)
-  271.37ms   232.16ms      0.86  binary_ops.Timeseries.time_timestamp_ops_diff_with_shift(None)
-    1.02μs   856.81ns      0.84  period.PeriodProperties.time_dayofyear('min')
-   27.18μs    21.73μs      0.80  timeseries.AsOf.time_asof_single
-   16.16ms    10.99ms      0.68  timeseries.ResampleSeries.time_period_downsample_mean
-    1.96μs     1.16μs      0.59  timestamp.TimestampProperties.time_offset(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-  585.07ns   324.17ns      0.55  timestamp.TimestampProperties.time_dayofweek(None, None)
-  312.95ns   154.08ns      0.49  timedelta.TimedeltaProperties.time_timedelta_nanoseconds
-  103.56ms    50.05ms      0.48  binary_ops.Timeseries.time_timestamp_ops_diff('US/Eastern')
-   25.66μs    11.82μs      0.46  timestamp.TimestampProperties.time_is_quarter_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
```

```
taskset 3 asv continuous -f 1.1 -E virtualenv master HEAD -b timeseries -b period -b timedelta -b timestamp
[...]
before     after       ratio
  [ae74c2b1] [cb73bd6b]
+  333.91ns   668.68ns      2.00  timestamp.TimestampProperties.time_is_leap_year(None, None)
+  242.27ns   446.63ns      1.84  timestamp.TimestampProperties.time_microsecond(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+    4.07ms     7.34ms      1.80  timeseries.TimeDatetimeConverter.time_convert
+    2.91ms     5.15ms      1.77  timeseries.ResampleDataFrame.time_max_numpy
+  305.16ns   427.57ns      1.40  timestamp.TimestampProperties.time_tz(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
+    1.27ms     1.72ms      1.36  binary_ops.Timeseries.time_series_timestamp_compare('US/Eastern')
+    41.97s     53.17s      1.27  gil.nogil_datetime_fields.time_period_to_datetime
+    5.71μs     7.03μs      1.23  timestamp.TimestampProperties.time_dayofyear(None, None)
+   11.65μs    14.19μs      1.22  timestamp.TimestampProperties.time_is_quarter_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+   11.93μs    14.36μs      1.20  timestamp.TimestampProperties.time_is_month_end(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
+    7.17μs     8.54μs      1.19  timestamp.TimestampProperties.time_is_year_end(None, 'B')
+    15.53s     18.30s      1.18  gil.nogil_datetime_fields.time_datetime_to_period
+     1.57s      1.78s      1.13  timeseries.Iteration.time_iter_periodindex
+    9.35ms    10.52ms      1.13  inference.DtypeInfer.time_timedelta64_2
+  135.65ms   152.27ms      1.12  timeseries.ToDatetime.time_iso8601_tz_spaceformat
+   11.92μs    13.35μs      1.12  timestamp.TimestampProperties.time_is_leap_year(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, 'B')
-    7.92μs     7.18μs      0.91  timestamp.TimestampProperties.time_is_quarter_end(None, 'B')
-    5.20ms     4.70ms      0.90  timeseries.ResampleSeries.time_timestamp_downsample_mean
-  973.90ns   877.14ns      0.90  period.PeriodProperties.time_quarter('M')
-   74.63ms    66.13ms      0.89  timeseries.ToDatetime.time_cache_false_with_dup_string_tzoffset_dates
-    1.38ms     1.22ms      0.88  binary_ops.Timeseries.time_series_timestamp_compare(None)
-  990.55ns   862.89ns      0.87  period.PeriodProperties.time_dayofyear('M')
-   11.07ms     9.61ms      0.87  timeseries.ResampleSeries.time_period_downsample_mean
-   54.89ms    47.60ms      0.87  timedelta.ToTimedelta.time_convert_string
-    2.91ms     2.51ms      0.86  timeseries.AsOf.time_asof_nan_single
-    8.41μs     6.88μs      0.82  period.Indexing.time_shallow_copy
-    9.00μs     7.33μs      0.81  timestamp.TimestampProperties.time_is_quarter_start(None, 'B')
-    6.10ms     4.76ms      0.78  timedelta.TimedeltaOps.time_add_td_ts
-    1.65ms     1.10ms      0.67  binary_ops.Timeseries.time_timestamp_series_compare(None)
-  476.91ns   314.19ns      0.66  timestamp.TimestampProperties.time_dayofweek(<DstTzInfo 'Europe/Amsterdam' LMT+0:20:00 STD>, None)
-    3.66ms     2.33ms      0.64  timeseries.ResampleDataFrame.time_mean_string
-    8.37ms     4.68ms      0.56  period.Algorithms.time_drop_duplicates('series')
-  642.83ns   328.42ns      0.51  timestamp.TimestampProperties.time_is_quarter_end(None, None)
-   56.74ms    26.92ms      0.47  binary_ops.Timeseries.time_timestamp_ops_diff_with_shift('US/Eastern')
-   36.83μs    16.73μs      0.45  timeseries.AsOf.time_asof_single_early
-  289.06ms   127.30ms      0.44  timeseries.AsOfDataFrame.time_asof
-  289.60ms   126.38ms      0.44  timeseries.AsOfDataFrame.time_asof_nan
-  199.34ms    67.25ms      0.34  binary_ops.Timeseries.time_timestamp_ops_diff_with_shift(None)
-   24.26ms     7.56ms      0.31  timeseries.DatetimeIndex.time_dti_tz_factorize
-   22.45ms     6.84ms      0.30  timeseries.DatetimeIndex.time_dti_factorize
-   50.20ms    10.71ms      0.21  binary_ops.Timeseries.time_timestamp_ops_diff('US/Eastern')
-   67.21ms    10.05ms      0.15  binary_ops.Timeseries.time_timestamp_ops_diff(None)
```
Since I'm going to have to run asv umpteen times to get reasonable results, I'm inclined to make a separate PR that just does the de-privatizing+centraling of _MONTHS/_MONTH_ALIASES/... and get that out of the way, cut the diff here back down.
I think this should be good to go.
It'd be nice to close this out since momentum for tslibs refactoring has waned.
thanks @jbrockmendel