ENH: Implement masked algorithm for value_counts
State: closed

- [ ] closes #xxxx (Replace xxxx with the GitHub issue number)
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.

this adapts the same methods we are using for unique and friends. We get a 5-10% performance improvement as the Number of NAs grows

Labels:
name: Algos
description: Non-arithmetic algos: value_counts, factorize, sorting, isin, clip, shift, diff
name: NA - MaskedArrays
description: Related to pd.NA and nullable extension arrays

Comments:
Does this close any open issues? Maybe https://github.com/pandas-dev/pandas/issues/44946?
There is an issue that includes all of our algorithms (mode is missing), we can close after I finish with that
merging this
This patch may have induced a performance regression. If it was a necessary behavior change, this may have been expected and everything is okay.

Please check the links below. If any ASVs are parameterized, the combinations of parameters that a regression has been detected for appear as subbullets.

 - [algos.isin.IsInLongSeriesLookUpDominates.time_isin](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInLongSeriesLookUpDominates.time_isin)
   - [dtype='float32'; MaxNumber=1000; series_type='random_hits'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInLongSeriesLookUpDominates.time_isin?p-dtype=%27float32%27&p-MaxNumber=1000&p-series_type=%27random_hits%27)
   - [dtype='int32'; MaxNumber=1000; series_type='random_misses'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInLongSeriesLookUpDominates.time_isin?p-dtype=%27int32%27&p-MaxNumber=1000&p-series_type=%27random_misses%27)
   - [dtype='float32'; MaxNumber=1000; series_type='monotone_hits'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInLongSeriesLookUpDominates.time_isin?p-dtype=%27float32%27&p-MaxNumber=1000&p-series_type=%27monotone_hits%27)
 - [algos.isin.IsInFloat64.time_isin](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInFloat64.time_isin)
   - [dtype='Float64'; title='only_nans_values'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInFloat64.time_isin?p-dtype=%27Float64%27&p-title=%27only_nans_values%27)
   - [dtype=<class 'numpy.float64'>; title='only_nans_values'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInFloat64.time_isin?p-dtype=%3Cclass%20%27numpy.float64%27%3E&p-title=%27only_nans_values%27)
   - [dtype='Float64'; title='few_different_values'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInFloat64.time_isin?p-dtype=%27Float64%27&p-title=%27few_different_values%27)
   - [dtype=<class 'numpy.float64'>; title='few_different_values'](https://asv-runner.github.io/asv-collection/pandas/#algos.isin.IsInFloat64.time_isin?p-dtype=%3Cclass%20%27numpy.float64%27%3E&p-title=%27few_different_values%27)
 - [frame_methods.SeriesNuniqueWithNan.time_series_nunique_nan](https://asv-runner.github.io/asv-collection/pandas/#frame_methods.SeriesNuniqueWithNan.time_series_nunique_nan)
 - [timeseries.DatetimeIndex.time_unique](https://asv-runner.github.io/asv-collection/pandas/#timeseries.DatetimeIndex.time_unique)
   - [index_type='repeated'](https://asv-runner.github.io/asv-collection/pandas/#timeseries.DatetimeIndex.time_unique?p-index_type=%27repeated%27)

Subsequent benchmarks may have skipped some commits. The link below lists the commits that are between the two benchmark runs where the regression was identified.

https://github.com/pandas-dev/pandas/compare/c8e7a98d6e8ef88d2c397d524dcfdb302f6fb4c8...6f0cd8d9ed251aa80f7415c565176fc33487110a

I agree that the regression look valid based on ASV, but 2 things point in another direction:

- I can not reproduce any of these regressions locally
- this pr didn't touch the code-path of isin at all

It's just very weird, not sure what to do
Ah, I didn't think to check if a dependency changed. Will check that.
This is mostly going through our own cython code, but nothing that I’ve touched. It’s very weird