[ 
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)

Reply via email to