REF: Special case NumericIndex._append_same_dtype()
State: closed

- [x] tests passed
- [x] passes `git diff master -u -- "*.py" | flake8 --diff`

Simple patch which results in a modest speedup (~8%) of the following:

```python
In [2]: idxes = [pd.Int64Index(range(i)) for i in range(1, 10)]*200
In [3]: %timeit idxes[0].append(idxes[1:])
```

I don't know whether this is worth the extra code... just inquiring so that I can finalize #16236.

Labels:
name: Performance
description: Memory or execution speed performance
name: Reshaping
description: Concat, Merge/Join, Stack/Unstack, Explode

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

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

```diff
@@            Coverage Diff             @@
##           master   #17307      +/-   ##
==========================================
- Coverage   91.03%   91.01%   -0.02%     
==========================================
  Files         162      162              
  Lines       49567    49572       +5     
==========================================
- Hits        45121    45117       -4     
- Misses       4446     4455       +9
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.79% <100%> (ø)` | :arrow_up: |
| #single | `40.25% <100%> (-0.06%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/indexes/numeric.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9udW1lcmljLnB5) | `97.22% <100%> (+0.03%)` | :arrow_up: |
| [pandas/core/dtypes/concat.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZHR5cGVzL2NvbmNhdC5weQ==) | `98.29% <100%> (+0.01%)` | :arrow_up: |
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `25% <0%> (-58.34%)` | :arrow_down: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.72% <0%> (-0.1%)` | :arrow_down: |

------

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

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

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

```diff
@@            Coverage Diff             @@
##           master   #17307      +/-   ##
==========================================
- Coverage   91.24%   91.23%   -0.02%     
==========================================
  Files         163      163              
  Lines       50168    50176       +8     
==========================================
  Hits        45777    45777              
- Misses       4391     4399       +8
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.04% <100%> (ø)` | :arrow_up: |
| #single | `40.28% <80%> (-0.06%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/indexes/numeric.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9udW1lcmljLnB5) | `97.27% <100%> (+0.03%)` | :arrow_up: |
| [pandas/core/dtypes/concat.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZHR5cGVzL2NvbmNhdC5weQ==) | `99.14% <100%> (+0.01%)` | :arrow_up: |
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `25% <0%> (-58.34%)` | :arrow_down: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.75% <0%> (-0.1%)` | :arrow_down: |
| [pandas/core/indexes/datetimes.py](https://codecov.io/gh/pandas-dev/pandas/pull/17307?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9kYXRldGltZXMucHk=) | `95.5% <0%> (+0.09%)` | :arrow_up: |

------

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

looks fine
can u add some asv for concat of Index
ones that hit your various paths would be good
IOW concat RangeIndex, IntIndex and Index cases would be great
> can u add some asv for concat of Index

``pd.concat()`` doesn't accept Index inputs, so I guess you mean ``Index.append()``: but then I think my previous PR already [addressed](https://github.com/pandas-dev/pandas/blob/2f00159da32c85c3b30b433f78a43e47677711a3/pandas/tests/indexes/test_range.py#L955) all the cases you mention. I'm pretty sure at least it touches the code paths I added in #16213, in #16236 and in this PR.
@toobaz indeed append, but question was about asv benchmark, not tests
> @toobaz indeed append, but question was about asv benchmark, not tests

Aha, OK, I had no idea of what "asv" meant. Looking into it.
I guess the benchmarking part is ready... but I wasn't able to test it (by the way, can you confirm that the content of [this page](https://github.com/pandas-dev/pandas/wiki/Performance-Testing) is obsolete?). Is it automatically ran anywhere?
@toobaz yeah, that page is out of date. New docs are [here](http://pandas-docs.github.io/pandas-docs-travis/contributing.html?highlight=asv#running-the-performance-test-suite). I'm tempted to just remove that wiki page. Any objections?

Results are run nightly and posted to http://pandas.pydata.org/speed/pandas/ (still setting this up)
I removed the content of the page and put a link to the contributing docs for now.
OK, the benchmarks now take ~5 ms. each.
Hello @toobaz! Thanks for updating the PR.







Cheers ! There are no PEP8 issues in this Pull Request. :beers: 

##### Comment last updated on October 28, 2017 at 06:48 Hours UTC
> can can you post these results (commit before your recent fix of range index concat) to this commit

You mean here?

(notice I changed the benchmarks so the ``RangeIndex`` special-casing is actually tested - indexes are consecutive)

Before special-casing ``RangeIndex.append()`` (with 94ef7b6a ):

```python
In [19]: %timeit ridx[0].append(ridx[1:])
100 loops, best of 3: 10.3 ms per loop

In [20]: %timeit iidx[0].append(iidx[1:])
100 loops, best of 3: 9.5 ms per loop

In [21]: %timeit oidx[0].append(oidx[1:])
100 loops, best of 3: 10.6 ms per loop

```

Before special-casing ``NumericIndex._concat_same_dtype()`` (with 2f00159d ):

```python
In [6]: %timeit ridx[0].append(ridx[1:])
100 loops, best of 3: 6.15 ms per loop

In [7]: %timeit iidx[0].append(iidx[1:])
100 loops, best of 3: 10.9 ms per loop

In [8]: %timeit oidx[0].append(oidx[1:])
100 loops, best of 3: 11.7 ms per loop
```

Now (with 6324b866 ):
```python
In [6]: %timeit ridx[0].append(ridx[1:])
100 loops, best of 3: 6.08 ms per loop

In [7]: %timeit iidx[0].append(iidx[1:])
100 loops, best of 3: 9.71 ms per loop

In [8]: %timeit oidx[0].append(oidx[1:])
100 loops, best of 3: 11.7 ms per loop
```
@toobaz I wanted to see the asv results for these benchmarks;
```asv continuous master thisbranch --bench concat `` (you might want to name these index_concat actually)

and I don't care about the internal benchmarks (a ``_*``) function, rather the public API ``.append()``
> @toobaz I wanted to see the asv results for these benchmarks;
> ```asv continuous master thisbranch --bench concat `` (you might want to name these index_concat actually)

OK, when I'll find the time to set up asv.

> and I don't care about the internal benchmarks (a _*) function, rather the public API .append()

Not following you here... indeed I'm testing only public methods.
asv_bench/benchmarks/index_concat.py is included but no changes.
> asv_bench/benchmarks/index_concat.py is included but no changes.

that's a leftover that should be removed, but the actual benchmarks are in the other file and time `append`
> asv_bench/benchmarks/index_concat.py is included but no changes.

oops fixed, sorry
@jreback @jorisvandenbossche 
Anyone has a hint of what's [happening](https://travis-ci.org/pandas-dev/pandas/jobs/268647210) in ``pandas.tests.indexes.test_category.TestCategoricalIndex.test_reindexing``? It fails randomly on Travis, (on [other branches](https://travis-ci.org/pandas-dev/pandas/jobs/268583991) too) and I really can't understand what could cause the error.
https://github.com/pandas-dev/pandas/issues/17323
Rebased and ran asv:

```
· Running 16 total benchmarks (2 commits * 1 environments * 8 benchmarks)
[  0.00%] · For pandas commit hash 3123fcff:
[  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
[  6.25%] ··· Running categoricals.Categoricals.time_concat                                                                                                                          4.67±0.07ms
[ 12.50%] ··· Running index_object.IndexOps.time_concat_int                                                                                                                           116±0.01ms
[ 18.75%] ··· Running index_object.IndexOps.time_concat_obj                                                                                                                            148±0.6ms
[ 25.00%] ··· Running index_object.IndexOps.time_concat_range                                                                                                                        67.2±0.06ms
[ 31.25%] ··· Running join_merge.Concat.time_concat_empty_frames1                                                                                                                        207±1μs
[ 37.50%] ··· Running join_merge.Concat.time_concat_empty_frames2                                                                                                                        211±2μs
[ 43.75%] ··· Running join_merge.Concat.time_concat_series_axis1                                                                                                                         111±1ms
[ 50.00%] ··· Running join_merge.Concat.time_concat_small_frames                                                                                                                      38.1±0.1ms
[ 50.00%] · For pandas commit hash e1dabf37:
[ 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
[ 56.25%] ··· Running categoricals.Categoricals.time_concat                                                                                                                          4.88±0.05ms
[ 62.50%] ··· Running index_object.IndexOps.time_concat_int                                                                                                                            131±0.2ms
[ 68.75%] ··· Running index_object.IndexOps.time_concat_obj                                                                                                                            144±0.7ms
[ 75.00%] ··· Running index_object.IndexOps.time_concat_range                                                                                                                         69.6±0.7ms
[ 81.25%] ··· Running join_merge.Concat.time_concat_empty_frames1                                                                                                                        208±2μs
[ 87.50%] ··· Running join_merge.Concat.time_concat_empty_frames2                                                                                                                        206±1μs
[ 93.75%] ··· Running join_merge.Concat.time_concat_series_axis1                                                                                                                         110±1ms
[100.00%] ··· Running join_merge.Concat.time_concat_small_frames                                                                                                                      38.2±0.2ms       before           after         ratio
     [e1dabf37]       [3123fcff]
-       131±0.2ms       116±0.01ms     0.88  index_object.IndexOps.time_concat_int

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.

```
IIRC was the purpose of this PR to make code more consistent; small perf bump as a result?
The patch avoids an int -> object -> int roundtrip by not relying on ``_concat_index_asobject``, hence yes, resulting in the modest speedup.
lgtm. pls rebase just to make sure. ping on green.
@jreback ping
thanks!