Remove unnecessary usage of _TSObject
State: closed

This is part 2 in an N-part series of PRs to disentangle inter-dependent pieces of tslib.pyx (and by extension, lib.pyx and period.pyx).

`tslib` has a `_TSObject` class that is used as a container during conversion steps.  In a number of the places where it is currently used, it is not needed.  All this PR does is remove it in cases where it is either unused or unneeded.

- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Labels:
name: Internals
description: Related to non-user accessible pandas implementation
name: Clean

Comments:
pls show asv for all time series operations

> pls show asv for all time series operations

I'll get that started shortly.
Between this and the experience last time with `Index._is_multi`, I'm not at all convinced these measurements are meaningful.

```
asv continuous -f 1.1 -E virtualenv master less_dts
[...]
before           after         ratio
     [3b02e73b]       [73e67ef7]
!           17.2s           failed      n/a  gil.nogil_datetime_fields.time_datetime_field_daysinmonth
!           39.4s           failed      n/a  gil.nogil_datetime_fields.time_datetime_field_normalize
!           20.5s           failed      n/a  gil.nogil_datetime_fields.time_datetime_field_year
+         231±1μs        31.5±40ms   136.06  indexing.MultiIndexing.time_series_xs_mi_ix
+     4.00±0.02ms            482ms   120.49  frame_methods.Reindex.time_reindex_axis0
+        263±10μs        5.53±20ms    20.99  indexing.MultiIndexing.time_frame_xs_mi_ix
+          73.2ms            611ms     8.35  packers.JSON.time_write_json_mixed_float_int_T
+       327±100ms            2.36s     7.21  gil.NoGilGroupby.time_sum_4_notp
+           801ms            5.14s     6.41  frame_methods.Reindex.time_reindex_axis1
+          74.6ms            440ms     5.90  packers.JSON.time_write_json_T
+     19.9±0.04ms          103±2ms     5.19  series_methods.series_isin_int64.time_series_isin_int64_large
+          74.0ms            380ms     5.14  packers.JSON.time_write_json_mixed_float_int_str
+        178±20ms            855ms     4.81  frame_methods.Shift.time_shift_axis_1
+         191±8ms         912±30ms     4.78  indexing.Int64Indexing.time_getitem_array
+        363±10ms            1.72s     4.73  frame_methods.Reindex.time_reindex_both_axes
+      1.31±0.01s            5.86s     4.47  reshape.reshape_unstack_large_single_dtype.time_unstack_with_mask
+           3.06s            13.7s     4.46  join_merge.MergeCategoricals.time_merge_cat
+           13.1s            58.3s     4.45  join_merge.JoinIndex.time_left_outer_join_index
+       837±300ms            3.63s     4.33  gil.NoGilGroupby.time_sum_8_notp
+           4.89s            20.2s     4.13  join_merge.MergeCategoricals.time_merge_object
+      1.45±0.02s            5.78s     3.98  gil.NoGilGroupby.time_groups_2
+        264±30ms       1.03±0.01s     3.90  indexing.Int64Indexing.time_loc_scalar
+        252±10ms         956±20ms     3.79  indexing.Int64Indexing.time_getitem_lists
+        295±10ms       1.10±0.03s     3.74  indexing.Int64Indexing.time_ix_list_like
+        652±50ms            2.38s     3.65  indexing.MultiIndexing.time_multiindex_large_get_loc_warm
+        295±10ms       1.07±0.05s     3.64  indexing.Int64Indexing.time_ix_array
+        607±10ms            2.20s     3.62  indexing.MultiIndexing.time_multiindex_large_get_loc
+        287±20ms       1.04±0.05s     3.62  indexing.Int64Indexing.time_loc_array
+        247±10ms          885±9ms     3.58  indexing.Int64Indexing.time_getitem_list_like
+        351±30ms            1.20s     3.42  frame_methods.Dropna.time_dropna_axis1_any_mixed_dtypes
+        298±10ms       1.01±0.04s     3.41  indexing.Int64Indexing.time_loc_list_like
+           1.72s            5.43s     3.16  join_merge.i8merge.time_i8merge
+          66.1ms            208ms     3.15  packers.JSON.time_write_json
+           994ms            2.95s     2.97  packers.JSON.time_write_json_lines
+           750ms            2.16s     2.88  frame_methods.frame_nunique.time_frame_nunique
+           17.4s            47.4s     2.73  gil.nogil_datetime_fields.time_datetime_field_day
+        338±30ms            894ms     2.64  indexing.MultiIndexing.time_multiindex_get_indexer
+         311±4ms         811±30ms     2.60  packers.Packers.time_packers_read_csv
+        432±30ms            1.07s     2.47  indexing.StringIndexing.time_getitem_label_slice
+        303±40ms         748±20ms     2.47  frame_methods.frame_duplicated.time_frame_duplicated
+       168±0.6ms         376±10ms     2.24  inference.to_numeric_downcast.time_downcast('string-float', 'signed')
+         175±2ms          384±4ms     2.20  inference.to_numeric_downcast.time_downcast('string-float', None)
+         177±2ms         384±10ms     2.17  inference.to_numeric_downcast.time_downcast('string-float', 'integer')
+        105±20ms            219ms     2.09  gil.NoGilGroupby.time_sum_4
+           136ms            248ms     1.82  packers.JSON.time_write_json_date_index
+           1.32s            2.12s     1.61  reindex.Reindexing.time_reindex_multiindex
+     2.48±0.01ms      3.77±0.03ms     1.52  groupby.groupby_datetimetz.time_groupby_sum
+           232ms            345ms     1.49  gil.nogil_read_csv.time_read_csv_datetime
+        262±90ms            390ms     1.49  join_merge.Align.time_series_align_int64_index
+      74.6±0.6ms          103±8ms     1.39  io_bench.frame_to_csv2.time_frame_to_csv2
+     9.27±0.06ms       12.7±0.2ms     1.37  algorithms.Algorithms.time_factorize_string
+       112±0.5ms          152±6ms     1.36  frame_methods.series_string_vector_slice.time_series_string_vector_slice
+           8.60s            11.7s     1.36  gil.NoGilGroupby.time_groups_4
+           2.37s            3.17s     1.34  stat_ops.FrameOps.time_op('median', False, 'float', 1)
+           14.0s            18.3s     1.31  gil.NoGilGroupby.time_groups_8
+      61.9±0.5μs       80.6±0.1μs     1.30  indexing.Int64Indexing.time_ix_slice
+      42.1±0.2ms         54.5±3ms     1.30  packers.STATA.time_write_stata_with_validation
+      56.2±0.6ms       69.6±0.7ms     1.24  packers.HDF.time_write_hdf_store
+           373ms            461ms     1.24  groupby.groupby_multi_index.time_groupby_multi_index
+           6.61s            7.95s     1.20  join_merge.ConcatPanels.time_c_ordered_axis2
+        91.4±3ms          109±3ms     1.19  gil.nogil_factorize.time_factorize_strings_4
+         418±4ms        496±0.9ms     1.19  timeseries.SemiMonthOffset.time_end_apply_index
+     3.14±0.08ms      3.70±0.08ms     1.18  timeseries.AsOf.time_asof_nan
+     2.75±0.03ms       3.25±0.2ms     1.18  timeseries.TimeSeries.time_large_lookup_value
+     1.44±0.01ms      1.70±0.05ms     1.18  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('MonthBegin', 1)
+           2.93s            3.44s     1.18  join_merge.ConcatFrames.time_c_ordered_axis0
+     1.98±0.01ms      2.31±0.01ms     1.17  groupby.GroupBySuite.time_mean('int', 10000)
+     14.9±0.03ms       17.4±0.2ms     1.16  frame_methods.Formatting.time_repr_tall
+           780ms            907ms     1.16  index_object.Multi2.time_sortlevel_int64
+        95.6±1ms          111±2ms     1.16  frame_methods.frame_insert_100_columns_begin.time_frame_insert_500_columns_end
+     4.87±0.04ms       5.52±0.1ms     1.13  groupby.groupby_float32.time_groupby_sum
+           2.30s            2.61s     1.13  stat_ops.FrameOps.time_op('median', True, 'int', 1)
+     3.24±0.09ms      3.67±0.06ms     1.13  timeseries.AsOf.time_asof
+     5.66±0.07ms      6.40±0.03ms     1.13  algorithms.Algorithms.time_add_overflow_pos_arr
+        1.38±0ms      1.56±0.04ms     1.13  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('MonthBegin', 2)
+        1.19±0ms         1.33±0ms     1.12  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('Nano', 1)
+       830±0.9μs         929±90μs     1.12  indexing.DataFrameIndexing.time_loc_dups
+           1.88s            2.11s     1.12  groupby.GroupBySuite.time_diff('float', 10000)
+          8.90ms           9.94ms     1.12  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('FY5253Quarter_1', 1)
+        2.18±0ms       2.42±0.2ms     1.11  timeseries.ResampleDataFrame.time_max_string
+        1.92±0ms      2.14±0.04ms     1.11  stat_ops.stats_rolling_mean.time_rolling_mean
+           1.44s            1.58s     1.10  groupby.GroupBySuite.time_rank('int', 10000)
+     18.4±0.02ms           20.2ms     1.10  join_merge.MergeAsof.time_by_int
-      2.03±0.1ms      1.84±0.03ms     0.91  reindex.Duplicates.time_frame_drop_dups_bool
-      5.56±0.1μs      5.04±0.01μs     0.91  indexing.IndexingMethods.time_get_loc_float
-        429±30ns          388±1ns     0.90  period.period_standard_indexing.time_shape
-        1.26±0ms         1.14±0ms     0.90  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('Hour', 2)
-      1.88±0.2ms         1.68±0ms     0.89  period.Algorithms.time_drop_duplicates_pseries
-     1.29±0.03ms         1.15±0ms     0.89  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('Micro', 2)
-      7.09±0.2ms       6.31±0.1ms     0.89  binary_ops.Ops2.time_frame_int_div_by_zero
-           8.50s            7.52s     0.89  join_merge.ConcatPanels.time_c_ordered_axis1
-     2.81±0.07ms      2.48±0.01ms     0.88  rolling.SeriesRolling.time_rolling_max_l
-         530±7ms          464±5ms     0.88  inference.to_numeric_downcast.time_downcast('string-nint', 'signed')
-        359±20μs          315±1μs     0.88  reindex.Reindexing.time_reindex_dates
-        512±10ms         448±10ms     0.88  inference.to_numeric_downcast.time_downcast('string-int', 'signed')
-        455±20ms          397±3ms     0.87  replace.replace_convert.time_replace_frame_timedelta
-           26.6s            23.1s     0.87  replace.replace_large_dict.time_replace_large_dict
-     1.21±0.05ms      1.05±0.02ms     0.87  replace.replace_replacena.time_replace_replacena
-        460±40ms         400±10ms     0.87  inference.to_numeric_downcast.time_downcast('string-nint', 'float')
-        798±30μs          692±1μs     0.87  reindex.LevelAlign.time_reindex_level
-        89.0±3μs       76.6±0.2μs     0.86  frame_methods.frame_dtypes.time_frame_dtypes
-        323±20ms       277±0.04ms     0.86  packers.packers_read_sql.time_packers_read_sql
-     3.20±0.09ms      2.74±0.01ms     0.86  frame_ctor.FrameConstructorDTIndexFromOffsets.time_frame_ctor('WeekOfMonth', 2)
-     4.91±0.07ms       4.19±0.2ms     0.85  binary_ops.Ops2.time_frame_int_mod
-        74.3±3μs       63.3±0.2μs     0.85  period.period_standard_indexing.time_series_loc
-        838±40μs          704±2μs     0.84  reindex.LevelAlign.time_align_level
-     21.5±0.04μs       18.0±0.4μs     0.84  timeseries.Offsets.time_custom_bday_incr
-          89.0μs           74.3μs     0.83  panel_methods.PanelMethods.time_shift_minor
-      9.29±0.4μs      7.73±0.01μs     0.83  period.Algorithms.time_drop_duplicates_pindex
-      14.3±0.7ms           11.8ms     0.83  join_merge.MergeAsof.time_on_int32
-        480±30ms          393±2ms     0.82  replace.replace_convert.time_replace_frame_timestamp
-      9.30±0.4ms      7.59±0.04ms     0.82  reindex.Duplicates.time_frame_drop_dups
-        97.6±5ms         79.2±1ms     0.81  plotting.TimeseriesPlotting.time_plot_regular_compat
-     35.7±0.07μs      28.9±0.04μs     0.81  indexing.Int64Indexing.time_iloc_list_like
-           48.4s            39.3s     0.81  gil.nogil_datetime_fields.time_period_to_datetime
-        404±30μs        325±0.9μs     0.80  reindex.Duplicates.time_series_drop_dups_int
-        98.3±8ms       78.8±0.8ms     0.80  gil.nogil_rolling_algos_fast.time_nogil_rolling_min
-     1.67±0.06ms      1.31±0.01ms     0.78  parser_vb.read_csv3.time_default_converter
-        341±10μs          266±5μs     0.78  reindex.FillMethod.time_pad
-        271±20μs        209±0.3μs     0.77  reindex.FillMethod.time_backfill_float32
-        515±20μs          396±2μs     0.77  reindex.Duplicates.time_series_drop_dups_string
-        10.5±1ms       7.94±0.1ms     0.76  reindex.LibFastZip.time_lib_fast_zip
-        567±60μs          429±3μs     0.76  period.Algorithms.time_value_counts_pindex
-      2.63±0.2ms      1.99±0.01ms     0.76  parser_vb.read_csv3.time_roundtrip_converter
-        641±30μs         485±10μs     0.76  reindex.Reindexing.time_reindex_columns
-        14.4±1ms      10.9±0.06ms     0.76  reindex.LibFastZip.time_lib_fast_zip_fillna
-      5.62±0.9ms      4.23±0.06ms     0.75  period.Constructor.time_from_pydatetime
-        342±50ms          250±4ms     0.73  replace.replace_convert.time_replace_series_timestamp
-        9.32±1ms      6.83±0.01ms     0.73  parser_vb.read_csv3.time_default_converter_with_decimal_python_engine
-      16.2±0.6ms       11.9±0.2ms     0.73  gil.nogil_read_csv.time_read_csv_object
-        15.3±1μs       11.1±0.1μs     0.72  period.period_standard_indexing.time_get_loc
-      3.67±0.4ms      2.65±0.01ms     0.72  reindex.Duplicates.time_frame_drop_dups_na_inplace
-        8.96±2μs      6.37±0.01μs     0.71  period.period_standard_indexing.time_shallow_copy
-        303±30μs        209±0.4μs     0.69  reindex.FillMethod.time_pad_float32
-      5.00±0.3ms      3.46±0.05ms     0.69  algorithms.Algorithms.time_duplicated_int
-           187ms            126ms     0.67  gil.nogil_kth_smallest.time_nogil_kth_smallest
-        19.8±3ms      13.3±0.04ms     0.67  parser_vb.read_csv1.time_sep
-           3.85s            2.53s     0.66  reshape.reshape_unstack_large_single_dtype.time_unstack_full_product
-      21.4±0.3ms      13.9±0.09ms     0.65  parser_vb.read_csv1.time_thousands
-           1.76s            978ms     0.55  groupby.Groups.time_groupby_groups('object_small')
-        17.9±1ms      9.83±0.03ms     0.55  reindex.Duplicates.time_frame_drop_dups_na
-        779±30μs         422±20μs     0.54  reindex.FillMethod.time_pad_daterange
-           1.29s            658ms     0.51  timeseries.AsOfDataFrame.time_asof
-           898ms            454ms     0.51  frame_methods.Dropna.time_dropna_axis0_all
-         466±7ms          234±6ms     0.50  inference.to_numeric_downcast.time_downcast('string-int', 'float')
-           196ms           89.7ms     0.46  packers.JSON.time_write_json_mixed_float_int
-        502±10ms          202±4ms     0.40  panel_ctor.Constructors1.time_panel_from_dict_all_different_indexes
-      1.06±0.01s         385±10ms     0.36  index_object.SetOperations.time_int64_symmetric_difference
-        424±20ms          148±4ms     0.35  panel_ctor.Constructors4.time_panel_from_dict_two_different_indexes
-           317ms            106ms     0.33  frame_methods.Dropna.time_dropna_axis0_any
-       395±0.1ms          116±1ms     0.29  index_object.SetOperations.time_int64_intersection
-           2.04s            599ms     0.29  frame_methods.Dropna.time_count_level_axis1_multi
-        187±50ms         52.5±2ms     0.28  parser_vb.read_csv_categorical.time_convert_post
-           1.89s            529ms     0.28  frame_methods.Dropna.time_count_level_axis0_multi
-           905ms         238±20ms     0.26  index_object.Multi1.time_duplicated
-           3.02s            788ms     0.26  frame_methods.Dropna.time_dropna_axis0_all_mixed_dtypes
-        624±20ms          153±6ms     0.24  binary_ops.Ops.time_frame_multi_and(True, 1)
-      1.04±0.07s         250±40ms     0.24  binary_ops.Ops.time_frame_multi_and(True, 'default')
-        384±20ms         87.7±4ms     0.23  index_object.SetOperations.time_int64_union
-        602±30ms         121±20ms     0.20  binary_ops.Ops.time_frame_multi_and(False, 'default')
-        411±10ms           72.1ms     0.18  frame_methods.Reindex.time_reindex_both_axes_ix
-     1.90±0.05ms        332±0.3μs     0.17  timeseries.DatetimeIndex.time_timeseries_is_month_start
-           3.45s            452ms     0.13  frame_methods.Dropna.time_count_level_axis1_mixed_dtypes_multi
-        161±20ms       15.6±0.1ms     0.10  parser_vb.read_csv2.time_comment
-           2.95s       18.6±0.1ms     0.01  join_merge.ConcatFrames.time_f_ordered_axis1

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
```
i would disagree

you are touching some very performance sensistive code

and you are removing type definitions

this he slowdown

you need to pick a benchmark ensure that there is no perf gap
I'll start by acknowledging that the edits to `_Timestamp.to_pydatetime` are probably less efficient than the status-quo version.  If that is causing a 100x slowdown in `Series.ix.__getitem__` or a 10x speedup in reading CSVs, then I understand this even less than I thought.

> and you are removing type definitions

Snark aside, `_Timestamp.to_pydatetime` is a case where this comment is correct, and I'll be happy to revert that.  But look at the others:

- `period.apply_mult` is never used.
- `src.datetime.convert_pydatetime_to_datetimestruct` is never even imported.
- `src.datetime.make_iso_8601_datetime` ditto.
- [...4 more of these in `src.datetime`]
- `tslib._is_multiple` is never used.
- `tslib.m8_weekday` is never used.
- `tslib.date_normalize` creates `tso = _TSObject()` and then never uses it.
- `tslib.get_date_name_field` declares `_TSObject ts` in its `cdef` block but then never uses it.
- `tslib.get_date_field` ditto.
- `Timestamp.replace` ditto.

Are any of these changes that could plausibly account for any changes in the asv output?  Honestly asking.

`tslib.get_start_end_field` actually has some action.  In the last block this PR deletes an occurrence of `ts = convert_to_tsobject(dtindex[i], None, None, 0, 0)` where `ts` is never used.  In each of the previous blocks, it replaces:

```
pandas_datetime_to_datetimestruct(dtindex[i], PANDAS_FR_ns, &dts)
ts = convert_to_tsobject(dtindex[i], None, None, 0, 0)
dow = ts_dayofweek(ts)
```
with
```
pandas_datetime_to_datetimestruct(dtindex[i], PANDAS_FR_ns, &dts)
dow = dayofweek(dts.year, dts.month, dts.day)
```

Note that `ts_dayofweek` is in inlined call that returns `dayofweek(ts.dts.year, ts.dts.month, ts.dts.day)` and that the call to `convert_to_tsobject` will end up making a redundant call to `pandas_datetime_to_datetimestruct`.

I have a hard time imagining how adding redundant calls to `pandas_datetime_to_datetimestruct` could slow things down.

All that said, I am the least experienced person here and am willing to be convinced.  But I see no evidence that the asv measurements above contain any meaningful information.
Yes, it is a problem with asv that the measurements are quite noisy, often too noisy to really rely upon (although, that noisy as the ones you show, I haven't seen that before on my laptop.). That said, asv is certainly still useful and captured regressions before. 

Given that asv is so noisy on your laptop, I would take some benchmarks out of it that could potentially be impacted (related to timeseries), and test the code snippet directly with `%timeit` (as I suggested before I think). When doing a performance related PR, I personally also more rely on that while developing than asv (it easier, quicker and more reliable for interactive use). 
Eg you mention `_Timestamp.to_pydatetime` and `tslib.get_start_end_field` as ones that can be impacted (for the better or the worse). So take a benchmark (or write a small code snippet yourself) that uses this, and run it a few times with `%timeit`. If I understand you correctly, one with `tslib.get_start_end_field` should even be faster.

Eg you can easily test `to_pydatetime`:

```
In [80]: ts = pd.Timestamp("2017-09-01 09:00:00")

In [81]: %timeit ts.to_pydatetime()
751 ns ± 6.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [82]: s = pd.date_range("2016-01-01", periods=10000, freq='H')

In [85]: %timeit s.to_pydatetime()
3.43 ms ± 39.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

Since you mention there are both clean-up of dead code as simplications (like the one in `to_pydatetime`), it's maybe easier to review to keep those changes separate?
OK.  Let's start with `to_pydatetime`.

```
In [3]: ts = pd.Timestamp("2017-09-01 09:00:00")
In [4]: %timeit ts.to_pydatetime()
```
In master this came back with 
```
The slowest run took 20.69 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 484 ns per loop
```
Under the PR this was in fact much slower:
```
In [4]: %timeit ts.to_pydatetime()
The slowest run took 109.78 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.95 µs per loop
```

So I reverted the edits to `py_datetime`.  Post-reversion that measurement back to parity (well,1.03% slower).
```
In [21]: %timeit ts.to_pydatetime()
The slowest run took 24.39 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 489 ns per loop
```

All subsequent timings here are post-reversion.
```
In [26]: s = pd.date_range("2016-01-01", periods=10000, freq='H')
In [27]: sb = pd.date_range("2016-01-01", periods=10000, freq='BH')
In [28]: %timeit s.to_pydatetime()
# PR     --> 100 loops, best of 3: 2.07 ms per loop
# master --> 100 loops, best of 3: 2.13 ms per loop
In [29]: %timeit sb.to_pydatetime()
# PR     --> 100 loops, best of 3: 2.08 ms per loop
# master --> 100 loops, best of 3: 2.12 ms per loop
```

Trying a method that will go through `get_start_end_field`.  The `BH` versions actually go through the changed weekday code paths:

```
In [30]: %timeit s.is_year_end
# PR     --> 1000 loops, best of 3: 307 µs per loop
# master --> 1000 loops, best of 3: 1.7 ms per loop

In [31]: %timeit sb.is_year_end
# PR     --> 1000 loops, best of 3: 362 µs per loop
# master --> 100 loops, best of 3: 1.78 ms per loop

In [32]: %timeit sb.is_quarter_start
# PR     --> 1000 loops, best of 3: 345 µs per loop
# master --> 100 loops, best of 3: 1.73 ms per loop
```


> Given that asv is so noisy on your laptop,

BTW, this is from a fairly beefy desktop in my basement.  There is non-zero background work running that can account for some noise, but both the level and variation should be much smaller than a laptop.

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=h1) Report
> Merging [#17297](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/3b02e73b856a6f8d53382bf3908f04447bf90e03?src=pr&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `n/a`.

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

```diff
@@            Coverage Diff             @@
##           master   #17297      +/-   ##
==========================================
- Coverage   91.03%   91.01%   -0.02%     
==========================================
  Files         162      162              
  Lines       49567    49567              
==========================================
- Hits        45123    45114       -9     
- Misses       4444     4453       +9
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.79% <ø> (ø)` | :arrow_up: |
| #single | `40.24% <ø> (-0.07%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `25% <0%> (-58.34%)` | :arrow_down: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.72% <0%> (-0.1%)` | :arrow_down: |
| [pandas/core/indexing.py](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhpbmcucHk=) | `93.94% <0%> (ø)` | :arrow_up: |
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `92.03% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17297?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/17297?src=pr&el=footer). Last update [3b02e73...a99133c](https://codecov.io/gh/pandas-dev/pandas/pull/17297?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Useful timings! 

> > Given that asv is so noisy on your laptop,

> BTW, this is from a fairly beefy desktop in my basement. There is non-zero background work running that can account for some noise, but both the level and variation should be much smaller than a laptop.

I don't know why it could be so variable on your desktop, all I can say is that I don't see *such* a large variation on mine. 
Eg I just ran (for another reason) a single benchmark today, one that in your timings above had a factor difference of 3.7, while here it was 1.06:

```
(dev) joris@joris-XPS-13-9350:~/scipy/pandas/asv_bench$ asv continuous v0.20.0 master -b indexing.Int64Indexing.time_ix_list_like
· Creating environments
· Discovering benchmarks
·· Uninstalling from conda-py3.6-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-pytest-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt.
·· Installing into conda-py3.6-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-pytest-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt..
· Running 2 total benchmarks (2 commits * 1 environments * 1 benchmarks)
[  0.00%] · For pandas commit hash 8354a1df:
[  0.00%] ·· Building for conda-py3.6-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-pytest-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt.................................................
[  0.00%] ·· Benchmarking conda-py3.6-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-pytest-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt
[ 50.00%] ··· Running indexing.Int64Indexing.time_ix_list_like                                                                                                                                                                                                           332±7μs
[ 50.00%] · For pandas commit hash 84fa7449:
[ 50.00%] ·· Building for conda-py3.6-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-pytest-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt..................................................
[ 50.00%] ·· Benchmarking conda-py3.6-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-pytest-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt
[100.00%] ··· Running indexing.Int64Indexing.time_ix_list_like                                                                                                                                                                                                          353±20μs
BENCHMARKS NOT SIGNIFICANTLY CHANGED.
```
thanks!