sqlite: remove the null prototype from result rows
Personne n'a encore pris cette issue.
- Langage dominant
- JavaScript
- Étoiles
- 122k
- Forks
- 37.3k
- Merge moyen
- 4 j 2 h
- PR mergées (30 j)
- 283
Description
Current behavior
Rows returned by get(), all() and iterate() are created with a null prototype. The V8 API that does this produces dictionary-mode objects, and V8 will not cache a prototype transition on a dictionary map, so every row also gets its own freshly allocated hidden class. Rows from the same statement therefore share no shape: they are slow to build, and every property access on them in user code is megamorphic.
Proposal
Drop the null prototype and build rows with v8::DictionaryTemplate, cached per statement. Rows become ordinary objects, and every row of a statement shares one hidden class.
Pros
all()is 10–37% faster depending on the query; reading the rows afterwards is far cheaper still.- Consistent with
run(), which already returns an ordinary object, and withbetter-sqlite3.
Cons
- Semver-major.
- Rows can no longer be indexed by untrusted keys without
Object.hasOwn()—row.toStringandrow.constructorstart resolving throughObject.prototype. - User code comparing rows against
{ __proto__: null, ... }breaks.
Prototype pollution is not a concern either way: rows are built by defining own properties directly, so a __proto__ column is an own property and never reaches Object.prototype.
I have benchmarks and a working implementation if there is interest.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par localiser les implémentations de get(), all(), iterate() ainsi que la gestion existante des résultats de run(), puis examinez comment la V8 API et v8::DictionaryTemplate sont utilisés. Examinez les benchmarks proposés et l’implémentation fonctionnelle mentionnés dans l’issue. Le travail est considéré comme terminé après l’évaluation du comportement des objets ordinaires, de la forme de ligne partagée, des performances et des problèmes de compatibilité liés à semver-major.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript, sqlite
- Domaine
- backend, databases
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100