WIP: PERF: Cythonize fillna
- [ ] closes #42147
- [ ] tests added / passed
- [ ] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing.html#code-standards) for how to run them
- [ ] whatsnew entry

Code is still pretty messy at this point, opening mainly for CI purposes. Also, this is my first time messing around with BlockManager so would appreciate a little extra scrutiny on that part.

Benchmarks
<Details>
```

       before           after         ratio
     [9f6a91ae]       [77c05634]
     <master>         <perf-fillna>
-      1.16±0.3ms         772±70μs     0.67  replace.FillNa.time_fillna(True)
-      6.78±0.7ms       4.48±0.3ms     0.66  replace.FillNa.time_fillna_df(False)
-      8.86±0.8ms       2.96±0.2ms     0.33  replace.FillNa.time_fillna_limit(False)
-      7.92±0.6ms       2.46±0.6ms     0.31  replace.FillNa.time_fillna_df(True)
-      6.15±0.5ms         810±60μs     0.13  replace.FillNa.time_fillna_limit(True)

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE INCREASED.
       before           after         ratio
     [9f6a91ae]       [77c05634]
     <master>         <perf-fillna>
+        644±10μs      1.15±0.04ms     1.79  replace.FillNa.time_replace(True)
+     4.14±0.08ms       5.43±0.3ms     1.31  replace.FillNa.time_replace(False)
-      4.10±0.2ms       2.30±0.2ms     0.56  replace.FillNa.time_fillna(False)
-     1.24±0.09ms         682±20μs     0.55  replace.FillNa.time_fillna(True)
-      6.98±0.4ms       2.61±0.4ms     0.37  replace.FillNa.time_fillna_limit(False)
-      6.61±0.3ms       1.57±0.1ms     0.24  replace.FillNa.time_fillna_df(True)
-      4.99±0.1ms         622±10μs     0.12  replace.FillNa.time_fillna_limit(True)

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE DECREASED.

       before           after         ratio
     [9f6a91ae]       [77c05634]
     <master>         <perf-fillna>

-      1.14±0.3ms         612±40μs     0.54  replace.FillNa.time_replace(True)
-        7.22±2ms       1.61±0.1ms     0.22  replace.FillNa.time_fillna_df(True)
-        8.97±2ms       2.00±0.2ms     0.22  replace.FillNa.time_fillna_limit(False)
-      5.47±0.2ms         639±30μs     0.12  replace.FillNa.time_fillna_limit(True)

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.
PERFORMANCE INCREASED.

```
</Details>
My main advice is to not worry about the Block stuff for now, just get the cython code working and write tests for it directly with ndarrays (and NDArrayBackedExtensionArray potentiall) @jbrockmendel Is it OK to do the NDArrayBacked.fillna changes in a followup, since this PR is already getting somewhat large? Good idea, yes. This pull request is stale because it has been open for thirty days with no activity. Please update or respond to this comment if you're still interested in working on this. Appears this PR has been dormant for a while closing to clear the queue. Feel free to reopen when you have time to work on this PR. 