In Szenario A habe ich die Eigenschaften einfach auf „undefiniert“ gesetzt. In Szenario B verwende ich den Löschoperator, um sie vollständig zu entfernen.
Code: Select all
const objA = {};
for (let i = 0; i < 10000; i++) objA['prop' + i] = i;
for (let i = 0; i < 5000; i++) objA['prop' + i] = undefined;
console.time('Access A');
let sumA = 0;
for (let i = 5000; i < 10000; i++) sumA += objA['prop' + i];
console.timeEnd('Access A');
const objB = {};
for (let i = 0; i < 10000; i++) objB['prop' + i] = i;
for (let i = 0; i < 5000; i++) delete objB['prop' + i];
console.time('Access B');
let sumB = 0;
for (let i = 5000; i < 10000; i++) sumB += objB['prop' + i];
console.timeEnd('Access B');
Mein technisches Verständnis und meine Verwirrung: Ich bin mir der versteckten Klassen (Maps) und des Inline-Caching von V8 bewusst. Meine Hypothese ist, dass das Löschen einen Übergang zum Wörterbuchmodus (Hash-Tabelle) auslöst, der die optimierten JIT-Zugriffspfade umgeht.
Ich habe jedoch ein paar spezifische Fragen, die ich in den V8-Dokumenten nicht finden konnte:
- Ist dieser Übergang zum Wörterbuchmodus dauerhaft für den Lebenszyklus dieses Objekts, oder kann V8 es wieder in eine versteckte Klasse zurückoptimieren, wenn das Objekt stabil bleibt?
- Warum gibt es einen so großen Unterschied zwischen delete und undefiniert, wenn die endgültige Anzahl aktiver Schlüssel gleich ist?
- Gibt es ein modernes V8-Flag oder ein internes Tool (wie --allow-natives-syntax), um zu bestätigen, ob ein Objekt für ein Wörterbuch „deoptimiert“ wurde?
Mobile version