PERF: avoid object conversion in fillna(method=pad|backfill) for masked arrays
State: closed

```
[ 75.00%] ··· frame_methods.Fillna.time_frame_fillna                                                                         ok
[ 75.00%] ··· ========= ======== ============ ============= ========== ============= =============
              --                                               dtype                              
              ------------------ -----------------------------------------------------------------
               inplace   method    float64       float32      object       Int64        Float64   
              ========= ======== ============ ============= ========== ============= =============
                 True     pad     3.44±0.3ms    2.64±0.2ms   307±10ms    3.97±0.2ms    3.72±0.1ms 
                 True    bfill    3.23±0.2ms    2.89±0.2ms   275±8ms     2.34±0.1ms   2.45±0.09ms 
                False     pad     3.62±0.1ms   2.06±0.01ms   181±3ms    4.23±0.07ms   4.16±0.07ms 
                False    bfill    3.59±0.2ms   2.06±0.02ms   186±6ms    4.35±0.09ms   4.18±0.06ms 
              ========= ======== ============ ============= ========== ============= =============
```

```
       before           after         ratio
     [2e5c28fc]       [d3ae0cf1]
     <master>         <BaseMaskedArray.fillna>
-     2.28±0.06ms      2.06±0.02ms     0.91  frame_methods.Fillna.time_frame_fillna(False, 'bfill', 'float32')
-      15.5±0.2ms      2.45±0.09ms     0.16  frame_methods.Fillna.time_frame_fillna(True, 'bfill', 'Float64')
-      16.5±0.2ms       2.34±0.1ms     0.14  frame_methods.Fillna.time_frame_fillna(True, 'bfill', 'Int64')
-      85.2±0.9ms      4.18±0.06ms     0.05  frame_methods.Fillna.time_frame_fillna(False, 'bfill', 'Float64')
-      86.6±0.6ms      4.16±0.07ms     0.05  frame_methods.Fillna.time_frame_fillna(False, 'pad', 'Float64')
-      90.9±0.8ms      4.35±0.09ms     0.05  frame_methods.Fillna.time_frame_fillna(False, 'bfill', 'Int64')
-      92.4±0.4ms      4.23±0.07ms     0.05  frame_methods.Fillna.time_frame_fillna(False, 'pad', 'Int64')
-        85.3±1ms       3.72±0.1ms     0.04  frame_methods.Fillna.time_frame_fillna(True, 'pad', 'Float64')
-        92.5±2ms       3.97±0.2ms     0.04  frame_methods.Fillna.time_frame_fillna(True, 'pad', 'Int64')

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE INCREASED.
```

Labels:
name: Missing-data
description: np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
name: Performance
description: Memory or execution speed performance
name: NA - MaskedArrays
description: Related to pd.NA and nullable extension arrays

Comments:
looks good. pls add a whatsnew note. you had a comment about multiple copies ; can try to handle here or make a new issue. ping when ready.
thanks @simonjayhawkins very nice
This was failing CI (now also on master):


```
=================================== FAILURES ===================================
________________ TestMissing.test_fillna_no_op_returns_copy[0] _________________
[gw1] linux -- Python 3.8.8 /home/vsts/miniconda3/envs/pandas-dev/bin/python

self = <pandas.tests.extension.test_sparse.TestMissing object at 0x7f0590718cd0>
data = [7, 33, 0, 95, 38, 0, 30, 26, 0, 47, 6, 0, 66, 4, 0, 57, 94, 0, 19, 23, 0, 48, 3, 0, 75, 74, 0, 51, 74, 0, 13, 73, 0, ...66, 67, 69, 70, 72, 73, 75,
       76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, 93, 94, 96, 97, 99],
      dtype=int32)

request = <FixtureRequest for <Function test_fillna_no_op_returns_copy[0]>>

    def test_fillna_no_op_returns_copy(self, data, request):
        if np.isnan(data.fill_value):
            request.node.add_marker(
                pytest.mark.xfail(reason="returns array with different fill value")
            )
>       super().test_fillna_no_op_returns_copy(data)

pandas/tests/extension/test_sparse.py:229: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pandas/tests/extension/base/missing.py:80: in test_fillna_no_op_returns_copy
    result = data.fillna(method="backfill")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = [7, 33, 0, 95, 38, 0, 30, 26, 0, 47, 6, 0, 66, 4, 0, 57, 94, 0, 19, 23, 0, 48, 3, 0, 75, 74, 0, 51, 74, 0, 13, 73, 0, ...66, 67, 69, 70, 72, 73, 75,
       76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, 93, 94, 96, 97, 99],
      dtype=int32)

value = None, method = 'backfill', limit = None

    def fillna(self, value=None, method=None, limit=None):
        """
        Fill missing values with `value`.
>           warnings.warn(msg, PerformanceWarning)
E           pandas.errors.PerformanceWarning: fillna with 'method' requires high memory usage.

pandas/core/arrays/sparse/array.py:672: PerformanceWarning
```