PERF: avoid copies if possible in fill_binop
This has a small perf bump, but more importantly is necessary for the blockwise frame-with-frame PR that is coming up.

```
import pandas as pd
from pandas.core.ops import *

arr = np.arange(10**6)
df = pd.DataFrame({"A": arr})
ser = df["A"]

%timeit result = df.add(df, fill_value=4)
7.77 ms ± 20.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)  <-- master
5.46 ms ± 36.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)  <-- PR

%timeit result = ser.add(ser, fill_value=1)
6.79 ms ± 56.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)  <-- master
4.65 ms ± 82.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)  <-- PR
```
