reduce_grouped's backed path rescans the group codes for every group

Ouverte Adaptée aux débutants
#113 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
88/100
Type d'issue
Refactorisation
Clarté
Clairement spécifiée
Activité
Active
Stack technique
python
Domaine
data, performance

Piste de recherche

Commencez dans src/mantispy/_core/_reduce.py, au niveau de la branche backed vers la ligne 178, puis lisez group_rows près de la ligne 49. Exécutez tests/test_backed.py::test_aggregate_and_feature_select_match et ajoutez une couverture utilisant un nombre de groupes supérieur au point de bascule ; le travail est terminé lorsque la réduction backed conserve les résultats attendus tout en évitant un parcours complet de codes pour chaque groupe.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Problem

src/mantispy/_core/_reduce.py:178, inside the backed branch's loop over groups:

for index in range(len(keys)):
    rows = np.flatnonzero((codes == index) & selected)

Two full-length passes over codes and selected per group, so O(n_groups x n_obs) in total. group_rows
(_reduce.py:49, in __all__, already used by tl/_design.py) does the same work once from one stable
ordering.

The cost depends entirely on the group count, and the crossover is around a few hundred groups:

rows groups per-group scan sorted once
1,000,000 141 (plates) 0.07 s 0.13 s
200,000 9,600 (wells) 0.76 s 0.03 s
1,000,000 50,000 (wells) 18.1 s 0.18 s

Grouping by plate is a wash, and the current form is marginally ahead. Grouping by well is the path
tl.aggregate takes on a cell-level object — tests/test_backed.py::test_aggregate_and_feature_select_match
calls exactly that — and there the scan adds 18 seconds of index arithmetic to a reduction that is already
paying one h5py read per group.

Proposed fix

  • Take the row indices from group_rows(codes, len(keys)) once before the loop, then restrict each
    group's rows with rows[selected[rows]]. Both give ascending indices within a group, so the reads and
    the statistic are unchanged.
  • Use it unconditionally rather than switching on the group count: the 0.06 s it gives up at plate counts
    is not worth a branch.
  • A test at a group count above the crossover, since the existing backed tests use two plates.

Found while reviewing #67. The in-memory branch below does not have this problem — it passes codes to the
kernel whole.

Langage dominant
Python
Étoiles
8
Forks
0
Merge moyen
10 h 48 min
PR mergées (30 j)
37

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de scverse/mantispy

Toutes les issues de scverse/mantispy

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.