PERF: Sparse IntIndex.make_union / Numeric ops
State: closed

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

Replace repeated `list.append` with `np.union1d` in `IntIndex.make_union`. `make_union` is used in numeric ops. 

**NOTE:** It is also possible to fix `IntIndex.intersect` to use `np.intersect1d`, but it doesn't increase the performance (because the length of the result is smaller).

The below microbench assumes array's 90% is sparse.

```
import numpy as np
import pandas as pd

np.random.seed(1)
N = 1000000
a = np.array([np.nan] * N)
b = np.array([np.nan] * N)

indexer_a = np.unique(np.random.randint(0, N, N / 10))
indexer_b = np.unique(np.random.randint(0, N, N / 10))
a[indexer_a] = np.random.randint(0, 100, len(indexer_a))
b[indexer_b] = np.random.randint(0, 100, len(indexer_b))

sa = pd.SparseArray(a)
sb = pd.SparseArray(b)
```
#### on current master

```
%timeit sa.sp_index.make_union(sb.sp_index)
#10 loops, best of 3: 52.7 ms per loop

%timeit sa + sb
10 loops, best of 3: 47.8 ms per loop
```
#### After this PR

```
%timeit sa.sp_index.make_union(sb.sp_index)
100 loops, best of 3: 11.6 ms per loop

%timeit sa + sb
100 loops, best of 3: 15.3 ms per loop
```


Labels:
name: Indexing
description: Related to indexing on series/frames, not to indexes themselves
name: Performance
description: Memory or execution speed performance
name: Numeric Operations
description: Arithmetic, Comparison, and Logical operations
name: Sparse
description: Sparse Data Type

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

> Merging [#13036](https://codecov.io/gh/pydata/pandas/pull/13036?src=pr) into [master](https://codecov.io/gh/pydata/pandas/branch/master?src=pr) will decrease coverage by **-0.00%**

``` diff
@@             master     #13036   diff @@
==========================================
  Files           136        136          
  Lines         50005      49994    -11   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
- Hits          42040      42027    -13   
- Misses         7965       7967     +2   
  Partials          0          0          
```
1. 2 files (not in diff) in `pandas/tseries` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/33104f50ac850f556f2052f58e268e4a5c49e815/changes?src=pr#70616E6461732F74736572696573) 
   - Misses `+1` 
   - Hits `-7`
2. 2 files (not in diff) in `pandas/io` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/33104f50ac850f556f2052f58e268e4a5c49e815/changes?src=pr#70616E6461732F696F) 
   - Misses `+1` 
   - Hits `-1`
3. 1 files (not in diff) in `pandas` were modified. [more](https://codecov.io/gh/pydata/pandas/commit/33104f50ac850f556f2052f58e268e4a5c49e815/changes?src=pr#70616E646173) 
   - Hits `-5`

> Powered by [Codecov](https://codecov.io?src=pr). Last updated by [e9ef522...33104f5](https://codecov.io/gh/pydata/pandas/compare/e9ef52246aacd694721f30e1d266c35bfedeba42...33104f50ac850f556f2052f58e268e4a5c49e815)

this looks fine for 0.18.1. do you want to add some sparse benchmarks?

OK, added whatsnew and bench.

```
   before     after       ratio
  [286782da] [a48f05db]
-   18.15ms     8.20ms      0.45  sparse.sparse_arithmetic.time_sparse_addition_10percent
-   18.17ms     8.08ms      0.44  sparse.sparse_arithmetic.time_sparse_division_10percent
-   17.97ms     7.73ms      0.43  sparse.sparse_arithmetic.time_sparse_addition_10percent_zero
-   18.47ms     7.84ms      0.42  sparse.sparse_arithmetic.time_sparse_division_10percent_zero
-    2.06ms   810.82μs      0.39  sparse.sparse_arithmetic.time_sparse_division_1percent
-    2.05ms   804.12μs      0.39  sparse.sparse_arithmetic.time_sparse_addition_1percent
```

ok ping on green.

Thanks, now green.

thanks @sinhrks