Skip to content

Share nested metadata values between parameter clones - #631

Draft
MaxGhenis wants to merge 2 commits into
masterfrom
share-parameter-metadata-on-clone
Draft

MaxGhenis wants to merge 2 commits into
masterfrom
share-parameter-metadata-on-clone

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

WIP. Benchmarks on policyengine-us and the full Core suite are running. Numbers will be filled in below.

Problem

Parameter.clone, ParameterAtInstant.clone, ParameterNode.clone and ParameterScale.clone each call copy.deepcopy(self.metadata). On policyengine-us one tree clone makes 1,257,541 ParameterAtInstant clones, and these deep copies are most of the cost of TaxBenefitSystem.clone(). Every reform build, behavioural-response measurement and Simulation.clone() in policyengine-us pays that cost.

Change

  • Each clone gets its own metadata dict, made with copy.copy, holding the source's values. None stays None and dict subclasses keep their type, as before.
  • interpolate_parameters replaces the interpolation dict it marks complete instead of editing it.

Plan

  • Audit metadata writes in Core, policyengine-us, -uk, -canada, -il, -ng, policyengine.py and the API repos
  • Example, property (Hypothesis) and differential tests
  • Before/after benchmark of TaxBenefitSystem.clone() on policyengine-us (time, peak RSS)
  • Full Core suite
  • Independent review

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 24, 2026 07:33
Parameter, ParameterAtInstant, ParameterNode and ParameterScale clones
deep-copied their metadata. On policyengine-us one tree clone makes
1,257,541 ParameterAtInstant clones, and those deep copies were most of
the cost of TaxBenefitSystem.clone().

Each clone now gets its own metadata dict (copy.copy, so None and dict
subclasses behave as before) holding the source's values. Top-level
edits stay on their side; a nested value must be replaced, not edited
in place. interpolate_parameters was the only writer that edited a
nested value after a clone exists (TaxBenefitSystem.__init__ clones the
tree into parameters.baseline before interpolating), so it now replaces
the interpolation dict it marks complete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
propagate_parameter_metadata hands each descendant the node's own
interpolation dict, so marking it complete in place skipped every child
after the first. Replacing the dict fixes that too; no PolicyEngine
country model uses propagated interpolation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant