Skip to content

L'arbre JSON de la scène est re-désérialisé à chaque frame (aucun cache entre les images) #159

Description

@LeadcodeDev

Trouvé en vérifiant un correctif du round 4, hors corpus d'audit.

La chaîne d'appel

render_frame_task (par frame)
render_scene_frame_scaled_with_prev_bg
prepare_scene (engine/render/scene.rs:549)
deserialize_children (engine/render/scene.rs:534)
→ pour chaque enfant : serde_json::from_value::<ChildComponent>(v.clone())

prepare_scene fait exactement trois lignes et n'a aucun cache. Le résultat ne dépend que de scene, jamais de frame_in_scene — il est donc identique pour toutes les frames d'une même scène, et recalculé intégralement pour chacune.

Le coût

Pour chaque frame et chaque enfant :

  1. un .clone() de la valeur serde_json du sous-arbre complet ;
  2. une désérialisation vers ChildComponent, dont le champ component est un enum untagged de 57 variants — serde les essaie dans l'ordre jusqu'à ce que l'un réussisse, en re-parsant le même objet à chaque tentative infructueuse.

Sur un rendu de 1200 frames avec 50 nœuds, cela fait 60 000 clones et 60 000 désérialisations d'un enum à 57 variants, pour un résultat rigoureusement constant.

Non mesuré. Je n'avance pas de chiffre parce que je n'ai pas profilé — mais l'ordre de grandeur mérite qu'on le fasse, d'autant que le lot paint du round 3 (PR #154) avait déjà trouvé un facteur comparable sur un autre chemin par frame (couche save_layer non bornée : 42–60 s → 0,5 s sur 60 frames).

Piste

Désérialiser une fois par scène, en amont de la boucle de frames, et passer le Vec<ChildComponent> aux fonctions de rendu. Les points d'entrée render_frame_v2 / render_frame_v2_scaled prennent déjà &[ChildComponent] en paramètre — ce sont les enveloppes render_scene_frame* qui rappellent prepare_scene à chaque fois. La correction consiste donc surtout à hisser l'appel d'un niveau, pas à réarchitecturer.

Attention à un détail : deserialize_children émet un avertissement sur stderr pour chaque enfant illisible. Aujourd'hui il sort une fois par frame ; le hisser le réduira naturellement à une fois par scène, ce qui est aussi le comportement souhaitable.

Vérification suggérée

Un benchmark avant/après sur un scénario réaliste (examples/mega-showcase.json), en comparant le temps de rendu total. Et un test qui affirme que prepare_scene n'est plus appelé depuis le chemin par frame.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions