Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Editable table data loading performance issue
Editable table data loading performance issue [message #1451707] Fri, 24 October 2014 07:08 Go to next message
Thomas Schär is currently offline Thomas SchärFriend
Messages: 4
Registered: February 2014
Junior Member
Hi!

Assume we have a table with about 15 columns (about 10 of them are editable boolean columns). Unfiltered, it holds rather many data rows (1000+). Now, loading data into the table with the replaceRowsByMatrix(new AtomicReference<Object>(...)) takes a long time. If the editable columns are not editable, the process takes place in reasonable time. Just to show the differences, filling in 19200 non-editable cells took on my machine 319ms, whereas it took over 3 minutes when 12000 of the cells were editable.

I found out, that the execPrepareEdit(...) method is called for each cell, which slows down the processing. So I have overwritten the table's loading method, setting a flag,
  @Override
  protected void execLoadData(SearchFilter filter) throws ProcessingException {
    isInitialLoading = true;
    getTable().replaceRowsByMatrix(new AtomicReference<Object>(execLoadTableData(filter)));
    isInitialLoading = false;
  }

which I then check for in the execPrepareEdit(...) method.
  @Override
  protected IFormField execPrepareEdit(ITableRow row) throws ProcessingException {
    if (getTable().isInitialLoading()) {
      return null;
    } else {
      return super.execPrepareEdit(row);
    }
  }


With this workaround the loading time is approximately equal with and without editable cells. But is there any danger that something is missed when I just skip the whole execPrepareEdit method? The values are inserted all correctly though, and the table behaves just normal. How did others overcome this problem?

Thanks!
Thomas
Re: Editable table data loading performance issue [message #1451897 is a reply to message #1451707] Fri, 24 October 2014 13:07 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie BressonFriend
Messages: 1243
Registered: October 2011
Senior Member
Hi,

Thanks for the report. Without having looked in the details, it seems to me that there is a bug in the table implementation. I would have said, that "PrepareEdit" should be loaded when the user click on the cell to edit it.

I have sent a mail to the scout-dev team. I hope they will be able to provide an answer. Next week is our first Scout User Group Meeting, the EclipseConEurope and the Eclipse Finance day. I am not sure if they will have time to have a look at it.

I hope someone will be able to provide you with detailed explanations.

.
Re: Editable table data loading performance issue [message #1479526 is a reply to message #1451897] Wed, 19 November 2014 14:00 Go to previous messageGo to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 567
Registered: October 2012
Location: Bern, Switzerland
Senior Member
I've been able to track this down.

Our initial assumption was, that execPrepareEdit() would be called exactly once when the user clicks into a cell that is editable.
The observed behaviour was that - depending on the table setup - execPrepareEdit() was called many times while filling the table and also when clicking on the row containing an editable cell.

I started tracing a different problem and in its course found the cause for the above issue. The secondary problem was as follows:

I had an AbstractColumn<SomeWrapperClassContainingInformationForCellDecorationAndDisplayStringCreationg>. The wrapper class also contained a list of strings from which a value could be chosen. In order to do this, we decided to use an AbstractSmartField<String>.

Our execPrepareEdit() looked like this:

  @Override
  protected IFormField execPrepareEdit(ITableRow row) throws ProcessingException {
      final SomeWrapperClassContainingInformationForCellDecorationAndDisplayStringCreationg wrapper = getValue(row);
      final List<String> values = new ArrayList<>();
      values.addAll(wrapper.getResourceTexts());
      if (wrapper.isDbMode()) {
        values.add(wrapper.getDbText());
      }
      AbstractSmartField<String> smartField = new AbstractSmartField<String>() {
        @Override
        protected Class<? extends ILookupCall<String>> getConfiguredLookupCall() {
          return OurStringListValueLookupCall.class;
        }

        @Override
        protected void execPrepareLookup(ILookupCall<String> call) throws ProcessingException {
          if (call instanceof OurStringListValueLookupCall) {
            OurStringListValueLookupCall lookupCall = ((OurStringListValueLookupCall) call);
            lookupCall.setValues(values);
            lookupCall.setHasDataBaseValue(wrapper.isDbMode());
          }
        }
      };
    }
    smartField.setValue(wrapper.getSelectedText());
    return smartField;
}


However, I was getting class cast exceptions in our LookupCalls getDataByKey() method because the LookupCall<String> could not cast a SomeWrapperClassContainingInformationForCellDecorationAndDisplayStringCreationg object to String.

This irritated me, because I was clearly calling smartField.setValue() with a string parameter. So obviously, some other piece of code was also using my edit field and directly using myColumn.getValue() as input parameter to the setValue() call.

I tracked down the culprit for both issues: AbstractColumn.validateColumnValue()

This method calls prepareEdit() which in turn calls execPrepareEdit() every time it is called and then sets the column content on that field:

            editor = prepareEdit(row);
            if (editor instanceof IValueField<?>) {
              ((IValueField<T>) editor).setValue(value);
            }


After overriding validateColumnValue() with an empty implementation for my column (no need to validate something chosen from a smart field) all my problems were gone:
- no more class cast exceptions
- only one call to execPrepareEdit exactly once, when I click into an editable cell

I did not track down the reason why validateColumnValue() was being called so often, but it was definitely a lot. In a table with 2 rows, each containing one editable column(), execPrepareEdit() was called 24 times from validateColumnValue() between the opening of the form and the end of initial rendering. Afterwards, each time I clicked on a row it was called 2 more times. With a table that small, this is not tragic. However, in our product we have tables with 2800 rows and 6 columns (of which 2 are editable) and I've had my scout client go into death spasms because several ten thousand instances of AbstractFields were created due to execPreapreEdit calls from validateColumnValue.

So there seem to be two issues:
- wasteful use of resources due to validateColumnValue() causing a new FormField to be created each time it is called (maybe the created form field could be cached on the table cell?)
- problems with the default implementation of validateColumnValue if the types of the Column and the EditField do not match (and there are use cases where this makes sense).
Re: Editable table data loading performance issue [message #1496944 is a reply to message #1479526] Wed, 03 December 2014 12:08 Go to previous messageGo to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 567
Registered: October 2012
Location: Bern, Switzerland
Senior Member
We've created a bug for this issue.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=452283

[Updated on: Wed, 03 December 2014 12:08]

Report message to a moderator

Re: Editable table data loading performance issue [message #1514644 is a reply to message #1451707] Wed, 17 December 2014 13:29 Go to previous messageGo to next message
Andreas Hoegger is currently offline Andreas HoeggerFriend
Messages: 185
Registered: February 2010
Senior Member
Thomas Schär wrote on Fri, 24 October 2014 09:08

With this workaround the loading time is approximately equal with and without editable cells. But is there any danger that something is missed when I just skip the whole execPrepareEdit method? The values are inserted all correctly though, and the table behaves just normal. How did others overcome this problem?


Hi Thomas
editable cells usually validates their values against the editor (form field) of the cell. Therefore there are some (more as expected) instances are created during the initial load of a table. The one and only side effect with your solution 'create the editor only in case the table is already initialized' is that values are not validated against their editors on initial load.

This workaround is practicable and not dangers at all.

/andreas
Re: Editable table data loading performance issue [message #1515897 is a reply to message #1514644] Thu, 18 December 2014 13:26 Go to previous message
Andreas Hoegger is currently offline Andreas HoeggerFriend
Messages: 185
Registered: February 2010
Senior Member
After analyzing the issue described is not so easy to fix.
Scout tables validate the input set to the table initially. So in case of editable cells the validation id passed to the editors the only way to have not a duplicated validation. The reason for several calls of the validation is the incremental data load.

Now we could discuss if a table should validate the data set to it or not. But this discussion has to take place in the new validation concept and not only for a single field (in this case the table). BUG 455621 is facing this issues.

To have a workaround so far use the way described by Thomas (first message in this thread) with an try... finally to to ensure the guard gets reset in all cases.

-andreas
Previous Topic:TablePage / TableField performance problems when removing a large number of rows
Next Topic:Bold label
Goto Forum:
  


Current Time: Sun Oct 22 21:22:16 GMT 2017

Powered by FUDForum. Page generated in 0.02092 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software