CLN: core/dtypes/cast.py::maybe_infer_to_datetimelike
State: closed

- [ ] closes #xxxx
- [ ] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Labels:
name: Clean

Comments:
what is the purpose here?
> what is the purpose here?

I was operating a little without thinking here & just following the TODO. It was originally added here:
https://github.com/pandas-dev/pandas/pull/24024/files#r244651601

On a closer look I think that whole if-else clause doesn't actually do anything. The body of this method only runs for object dtype:
https://github.com/pandas-dev/pandas/blob/de5349a4820fd35aeac35ef2538eb564e0e11292/pandas/core/dtypes/cast.py#L1310-L1327
I pushed a commit that gets rid of the entire `if-elif` block and if CI passes then that seems like good cleanup
pls run some asv's this is a very hot path (we hit this on a lot of construction). I think this was done for performance.
> pls run some asv's this is a very hot path (we hit this on a lot of construction). I think this was done for performance.

That sounds right. The `period` asv is the one sensitive to this. With the check removed:
```
       before           after         ratio
     [4a08c02b]       [d80cc096]
     <GH37037~2>       <CLN-maybe_infer_to_datetimelike>
+     3.26±0.08ms       27.5±0.6ms     8.44  period.DataFramePeriodColumn.time_set_index
+      7.90±0.1ms       9.55±0.3ms     1.21  timeseries.ResampleSeries.time_resample('period', '5min', 'ohlc')
+      12.8±0.1μs       15.1±0.4μs     1.18  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 2000, datetime.timezone(datetime.timedelta(seconds=3600)))
+     12.6±0.08μs       14.5±0.9μs     1.15  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 1000, datetime.timezone(datetime.timedelta(seconds=3600)))
+     7.93±0.04μs       9.05±0.4μs     1.14  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 1011, None)
+     12.5±0.08μs         14.0±1μs     1.12  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 1011, datetime.timezone(datetime.timedelta(seconds=3600)))
+     6.66±0.05μs       7.42±0.2μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 7000, datetime.timezone(datetime.timedelta(seconds=3600)))
+     2.06±0.01μs      2.30±0.08μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 8000, None)
+     1.95±0.01μs      2.17±0.07μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 7000, datetime.timezone.utc)
+     6.65±0.07μs       7.40±0.2μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 6000, datetime.timezone(datetime.timedelta(seconds=3600)))
+     8.05±0.03μs       8.94±0.5μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 2000, datetime.timezone.utc)
+     6.60±0.09μs       7.27±0.2μs     1.10  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(0, 1000, datetime.timezone(datetime.timedelta(seconds=3600)))
+     7.84±0.03μs       8.63±0.5μs     1.10  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 1011, datetime.timezone.utc)
+     5.90±0.09μs       6.50±0.3μs     1.10  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 6000, tzfile('/usr/share/zoneinfo/Asia/Tokyo'))

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE DECREASED.
```
Looking into whether the original commit (adding a Timedelta check) improves anything
Seems like a mixed bag with the addition of the Timedelta check, with some significant degradations:
```
       before           after         ratio
     [4a08c02b]       [fdaefd1c]
     <GH37037~2>       <CLN-maybe_infer_to_datetimelike>
+      8.09±0.1ms       9.83±0.4ms     1.21  timeseries.ResampleSeries.time_resample('period', '5min', 'ohlc')
+     2.19±0.07μs       2.53±0.2μs     1.15  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 1000, tzlocal())
+      8.31±0.1μs         9.55±1μs     1.15  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 2000, None)
+      2.16±0.1μs       2.44±0.2μs     1.13  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 1011, None)
+      6.68±0.2μs       7.53±0.1μs     1.13  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 1011, datetime.timezone(datetime.timedelta(seconds=3600)))
+      6.64±0.2μs       7.41±0.3μs     1.12  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 4000, datetime.timezone(datetime.timedelta(seconds=3600)))
+      6.67±0.1μs       7.44±0.2μs     1.12  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 2011, datetime.timezone(datetime.timedelta(seconds=3600)))
+     2.19±0.08μs      2.42±0.04μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 3000, tzlocal())
+         665±3μs         736±40μs     1.11  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 8000, None)
+     2.09±0.08μs      2.30±0.03μs     1.10  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(1, 1000, datetime.timezone.utc)
-        648±20μs          589±5μs     0.91  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 1011, None)
-        861±40μs          780±9μs     0.91  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 12000, tzfile('/usr/share/zoneinfo/Asia/Tokyo'))
-     1.21±0.09ms      1.09±0.01ms     0.90  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 10000, tzlocal())
-      9.98±0.7μs       8.91±0.2μs     0.89  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 8000, None)
-        15.3±2μs       13.6±0.2μs     0.89  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 12000, tzfile('/usr/share/zoneinfo/Asia/Tokyo'))
-        795±20μs          704±3μs     0.88  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 1011, <DstTzInfo 'US/Pacific' LMT-1 day, 16:07:00 STD>)
-     1.04±0.09ms          913±5μs     0.88  reindex.ReindexMethod.time_reindex_method('backfill', <function period_range>)
-        123±10ms          108±1ms     0.87  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 2011, tzlocal())
-        15.7±1μs       13.6±0.3μs     0.86  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 7000, datetime.timezone(datetime.timedelta(seconds=3600)))
-        971±30μs          837±9μs     0.86  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 12000, <DstTzInfo 'US/Pacific' LMT-1 day, 16:07:00 STD>)
-        810±20μs          694±7μs     0.86  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 12000, datetime.timezone(datetime.timedelta(seconds=3600)))
-         130±4ms          110±3ms     0.85  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 1000, tzlocal())
-      1.85±0.1ms       1.57±0.2ms     0.85  indexing.NonNumericSeriesIndexing.time_getitem_list_like('period', 'non_monotonic')
-         134±9ms          112±3ms     0.84  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(10000, 11000, tzlocal())
-      8.40±0.9ms      6.99±0.08ms     0.83  period.PeriodIndexConstructor.time_from_ints('D', False)
-      1.34±0.2ms      1.07±0.01ms     0.80  tslibs.period.TimeDT64ArrToPeriodArr.time_dt64arr_to_periodarr(100, 12000, tzlocal())

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE DECREASED.
```
Should I just close this? Alternatively could restore original code but remove the TODO since I guess perf is the reason Timedelta shouldn't be included in that check
can push the code with the Timedelta check added. I am +1 on simplyfing this if we can (even at a small perf hit)
> can push the code with the Timedelta check added. I am +1 on simplyfing this if we can (even at a small perf hit)

Ok! Done that
> > can push the code with the Timedelta check added. I am +1 on simplyfing this if we can (even at a small perf hit)
> 
> Ok! Done that

oh i see, its actually *longer* here. umm is there any perf difference?
The tslibs asvs 100% should not be affected by this.  They depend _only_ on code in _libs.tslibs.
> The tslibs asvs 100% should not be affected by this. They depend _only_ on code in _libs.tslibs.

Right, that makes sense. I have no explanation for why they were affected

Non tslibs asvs when using `if hasattr(value, "dtype") and not is_object_dtype(value.dtype): return value`:
```
       before           after         ratio
     [901b1a7e]       [cfc59f06]
     <CLN-maybe_infer_to_datetimelike^2>       <CLN-maybe_infer_to_datetimelike>
+         910±6μs       1.22±0.1ms     1.34  reindex.ReindexMethod.time_reindex_method('backfill', <function period_range>)
+         945±8μs      1.16±0.09ms     1.23  reindex.ReindexMethod.time_reindex_method('pad', <function period_range>)
+     3.23±0.03ms       3.86±0.3ms     1.19  period.DataFramePeriodColumn.time_set_index
+         842±4μs         977±90μs     1.16  period.Indexing.time_align
+      1.08±0.04s       1.23±0.01s     1.13  timeseries.Iteration.time_iter(<function period_range>)
+         250±2μs          279±9μs     1.12  period.Indexing.time_intersection
+         647±5μs         721±40μs     1.11  period.Algorithms.time_value_counts('index')
+      95.2±0.4μs          106±4μs     1.11  period.DataFramePeriodColumn.time_setitem_period_column
+         289±2μs         321±20μs     1.11  period.Algorithms.time_drop_duplicates('series')
+         609±3μs         675±30μs     1.11  period.Algorithms.time_value_counts('series')

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE DECREASED.
```
With the current commit (added Timedelta checks, fixed the Series check according to @jbrockmendel suggestion) asvs are:
```
asv continuous -f 1.1 upstream/master HEAD -b period
(...)
       before           after         ratio
     [0647f02c]       [8a3d6a3d]
     <master>         <CLN-maybe_infer_to_datetimelike>
+     1.45±0.07ms      1.71±0.03ms     1.18  indexing.NonNumericSeriesIndexing.time_getitem_list_like('period', 'non_monotonic')
+         249±2μs         280±20μs     1.13  period.Indexing.time_intersection
+         456±3ns          509±9ns     1.12  dtypes.Dtypes.time_pandas_dtype(period[D])

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE DECREASED.
```
I removed the `Timedelta` checks but added the `DatetimeIndex` -> `DatetimeArray` bug fix that @jbrockmendel pointed out. Now this PR is performance neutral for `asv continuous -f 1.1 upstream/master HEAD -b period`

Closing as no longer relevant