PERF: NDArrayBacked in cython
Context: looking at backing `DatetimeBlock`/`TimedeltaBlock` by `DatetimeArray`/`TimedeltaArray` directly (as opposed to the status quo where we back by ndarrays) and profiling, the constructors stand out as a major source of overhead.  

Idea: put the ndarray-wrapping methods in cython

Upsides: performance!  stats currently pasted into the NDArrayBacked docstring:

```
import pandas as pd
from pandas._libs.lib import NDArrayBacked as cls

dti = pd.date_range("2016-01-01", periods=3)
dta = dti._data
arr = dta._ndarray

obj = cls._simpler_new(arr, arr.dtype)

# for foo in [arr, dta, obj]: ...

%timeit foo.copy()
299 ns ± 30 ns per loop     # <-- arr underlying ndarray (for reference)
530 ns ± 9.24 ns per loop   # <-- dta with cython NDArrayBacked
1.66 µs ± 46.3 ns per loop  # <-- dta without cython NDArrayBacked  <-- i.e. master
328 ns ± 5.29 ns per loop   # <-- obj with NDArrayBacked.__cinit__
371 ns ± 6.97 ns per loop   # <-- obj with NDArrayBacked._simpler_new

%timeit foo.T
125 ns ± 6.27 ns per loop   # <-- arr underlying ndarray (for reference)
226 ns ± 7.66 ns per loop   # <-- dta with cython NDArrayBacked
911 ns ± 16.6 ns per loop   # <-- dta without cython NDArrayBacked  <-- i.e. master
215 ns ± 4.54 ns per loop   # <-- obj with NDArrayBacked._simpler_new
```

i.e. `dta.copy()` is 3x faster, and within 2x of numpy.  With further tweaks we could get within 10% of numpy (the 328 ns number).  `dta.T` is 4x faster and within 2x of numpy.

(T is more-improved than copy bc we override copy in python to copy `.freq`)

Downsides: 1) pickle is a PITA, 2) constructor gymnastics

Future:
- lib.pyx is likely not the best place for this
- can squeeze out more perf if we use `__cinit__`; requires more constructor gymnatics
- can use in PeriodArray, Categorical, PandasArray with some effort
- more methods could be optimized
