PERF: further improve take (reindex/unstack) for ArrayManager
A few related changes to `take_1d` / `ArrayManager.unstack`:

- Check in `ArrayManager.unstack` whether there will be missing values introduced or not, and if not, pass `allow_fill=False` to the `take` function, so this can take a more performant path (and doesn't need to check repeatedly for `indexer == -1`). And the same for `ArrayManager.reindex_indexer`.
- In the `take_1d`, if `allow_fill=False`, use the numpy `take` instead of our own cython implementation (numpy is a bit faster).
-  Move the `ensure_int64` check for the indexer out of the shared `_take_preprocess_indexer_and_fill_value`. This way, we can do this once in ArrayManager.unstack and avoid doing it repeatedly for the same indexer inside `take_1d`.

Case from the `frame_methods.py::Unstack.time_full_product` ASV benchmark:

```python
dtype = 'int'
m = 100
n = 1000

levels = np.arange(m)
index = pd.MultiIndex.from_product([levels] * 2)
columns = np.arange(n)
values = np.arange(m * m * n).reshape(m * m, n)

df = pd.DataFrame(values, index, columns)
df_am = df._as_manager("array")
```

with the combined changes, this gives:

```
In [2]: %timeit df_am.unstack()
1.09 s ± 68.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)  <-- master
276 ms ± 19.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)  <-- PR
```