[ https://issues.apache.org/jira/browse/WICKET-6774?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17097287#comment-17097287 ]
Thomas Heigl commented on WICKET-6774: -------------------------------------- Hi [~papegaaij]: {quote}We should be very careful with these micro benchmarks. Your numbers already show a very interesting case: your testcase contains an error on component2. It is constructed with the same parameters as component0, still the numbers are way off. Either your actual testcase is somewhat different or the difference in numbers has a whole different cause. It can be a difference in memory allocation, but it can also be that your system is throttling down due to heat or power consumption. Interestingly enough, I'm seeing similar numbers. I don't have a good explanation. {quote} I might have temporarily fixed that mistake and then later changed it back when switching between branches. I frequently stashed and reverted to older versions of the benchmark during my experiments. But that does not explain why you see similar numbers. I have no explanation either. {quote}More importantly, we are only testing detach. I'm not saying that detach performance can be increased, but this case is very limited. During detach of your testcase, {{setMetaData}} is called many times with data = null. This is the only call to any of the state of the components. Therefore, it makes sense that in this particular case performance is limited by this call, and eliminating it will increase performance for this case. However, this is not a typical application and the other elements of the state are accessed by other parts of Wicket. Optimizing for this case may reduce performance for the other (probably more important) cases. That being said, I do think we should continue profiling and benchmarking component state, but in a richer setup. I've continued to improve the performance of my branch. For the detach case, I'd consider it on par with or faster than master. {quote} I agree. Detach shouldn't be the main test-case. I only created the benchmark this way to demonstrate a performance issue I saw in the profiler on production. This was not intended to be a performance test that can be used to fine-tune component state management. {quote}I think we should add the feedback flag. The setMetaData call per component is a lot more expensive than a simple flag check. Not many components do have feedback. {quote} Either that or a general {{FLAG_METADATA_SET}} would be the simplest performance improvement that can be made to the current implementation. The general flag has the advantage that it can be used to return early when clearing other metadata. MarkupContainer clears removals on every detach by setting the metadata to null: {code:java} @Override protected void onDetach() { super.onDetach(); removals_clear(); } private void removals_clear() { setMetaData(REMOVALS_KEY, null); } {code} If we had {{FLAG_METADATA_SET, }}{{setMetaData}} could return immediately like this: {code:java} @Override public final <M extends Serializable> Component setMetaData(final MetaDataKey<M> key, final M object) { if (!getFlag(FLAG_METADATA_SET) && object == null) { return this; } ... } {code} > Separate model, behaviors and metadata into separate fields > ----------------------------------------------------------- > > Key: WICKET-6774 > URL: https://issues.apache.org/jira/browse/WICKET-6774 > Project: Wicket > Issue Type: Improvement > Components: wicket-core > Affects Versions: 9.0.0-M5 > Reporter: Thomas Heigl > Priority: Major > Attachments: benchmarks.png > > > While investigating performance issues with metadata in WICKET-6771, I > discovered that significant performance gains can be achieved by separating > models, behaviors, and metadata into separate fields. > Currently, all three types of data are stored in a single, untyped field > {{Component.data}}. The idea is to minimize memory overhead by creating as > few objects as possible. > If a model or a single behavior or metadata is added, {{data}} stores only a > reference to the object. When additional data is added, the reference becomes > an array. > This is the most memory-efficient way to store these three types of data. But > it comes with a cost: code to manipulate that data structure is complex and > not as efficient because it has to take all possible combinations of data > into account. > I suggest introducing 3 separate fields for the 3 types of data, trading a > little bit of memory for reduced complexity and performance gains. -- This message was sent by Atlassian Jira (v8.3.4#803005)