This is an automated email from the ASF dual-hosted git repository. papegaaij pushed a commit to branch wicket-6774 in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 234ff1c36a51f6acc41b9371be7d3288e5b7ea0c Author: Emond Papegaaij <[email protected]> AuthorDate: Sat Sep 5 14:18:23 2026 +0200 WICKET-6774: do not store a model that lazy initialisation did not find getDefaultModel() memoises the inherited model lookup: when a component has no model of its own, initModel() walks the parent chain for an IComponentInheritedModel and, on a hit, allocates a wrapper bound to this component, which setModelImpl() then stores so the next call is cheap. The matching invalidation lives in detach(). It also stored the misses, and storing a miss records nothing, because the null leaves FLAG_MODEL_SET clear and the next call walks the hierarchy again anyway. So the write bought nothing while costing two field stores, to data and to flags, on every call for a component without a model. Most components have none: of 548285 components measured on a production application, 61% carry no model. Master pays nothing here only incidentally, its setModelImpl() falling through both branches when the flag is clear. Skipping the call is a no-op by construction. FLAG_MODEL_SET is set exactly when a non-null model was stored, and only setModelImpl() writes the model slot, so getModelImpl() returning null implies the flag is clear; with the flag clear ComponentState.setModel(null, data, false) returns data unchanged down every branch and the setFlag() is already false. Nothing overrides setModelImpl() or getModelImpl(), and initModel() raises FLAG_INHERITABLE_MODEL only on the path that returns non-null. Measured with wicket-benchmarks, reading models over an array of components, harness overhead subtracted, ns per component: master before after model present 1.117 0.871 0.889 model absent 0.316 1.399 0.352 mixed 0.654 1.197 0.340 The absent path was 4.4x master and is now level with it, and reading state over interleaved components is faster than master rather than 83% slower. Note that a miss is still not memoised, on master or here: every getDefaultModel() on a component without a model re-walks its ancestors. Fixing that needs somewhere to record that the lookup already failed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> --- wicket-core/src/main/java/org/apache/wicket/Component.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java b/wicket-core/src/main/java/org/apache/wicket/Component.java index 9bd693b7e3..896cf8c2f1 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Component.java +++ b/wicket-core/src/main/java/org/apache/wicket/Component.java @@ -1400,7 +1400,10 @@ public abstract class Component { // give subclass a chance to lazy-init model model = initModel(); - setModelImpl(model); + if (model != null) + { + setModelImpl(model); + } } return model;
