Bug #8196
Reduce number of AbstractTempTable._hasRecords calls to avoid BufferManager.activeBuffers
100%
Related issues
History
#1 Updated by Dănuț Filimon over 2 years ago
| Counts | Reclaiming disabled | 1s lifespan | 10s lifespan |
|---|---|---|---|
| No matching persistence | 285708435 | 5874605 | 3564224 |
| No records to associate | 31051569 | 26227813 | 26226169 |
| Records associated | 2517852 | 614027 | 613197 |
| Sessions created | 124912 | 1127 | 89 |
| Sessions reclaimed | 0 | 123767 | 124805 |
AbstractTempTable._hasRecords calls and separated them from other sources in the table below (also copied from #7167-12).
| Counts | from AbstractTempTable | from BufferManager / other |
|---|---|---|
| Number of calls | 11312 | 1188 |
| No matching persistence | 3534544 | 2457786 |
| No records to associate | 26237166 | 1974 |
| Records associated | 601546 | 1123 |
The purpose of this issue is to find a way to reduce the number of calls to BufferManager.activeBuffers that are resulted from AbstractTempTable._hasRecords.
#2 Updated by Dănuț Filimon over 2 years ago
- Related to Bug #7167: Associating records from opened buffers to new sessions is slow added
#3 Updated by Dănuț Filimon over 2 years ago
After a fix involving going over the buffers from AbstractTempTable.allBuffers and execute the same logic from activeBuffers, I noticed that whenever _hasRecords is called and the activeBuffers is reached, false is always returned. This means that the condition where the temp table is checked to be equal to the current object is never true. The logic was first introduced in trunk/rev.10452, since then it was improved by direct access.
#4 Updated by Alexandru Lungu over 2 years ago
Danut, the code using allBuffers is meant to check records that were not yet flushed to the database (transient) and are stored only in FWD. Thus, we need to check all buffers to see if there is a record that was not flushed yet.
- Check if we really need to check the transient records for some use-cases.
- The code is called from
TempTableBuilder.clear- is this actually considering transient records? - It is also called by
AbstractTempTable.setCanUndo- is this a bottleneck (?) how often is_hasRecordshit from this spot?
- The code is called from
- Iterate only the buffers over that table; not all open buffers.
#5 Updated by Dănuț Filimon over 2 years ago
The POC application calls AbstractTempTable.hasRecords and clear/setCanUndo are not called at all. I noticed that this method can be directly called from the converted code (in this case, in a for each loop).
#6 Updated by Dănuț Filimon over 2 years ago
- Assignee set to Dănuț Filimon
- Status changed from New to WIP
#7 Updated by Dănuț Filimon over 2 years ago
Alexandru Lungu wrote:
This can be improved in two ways:
- Check if we really need to check the transient records for some use-cases.
- The code is called from
TempTableBuilder.clear- is this actually considering transient records?- It is also called by
AbstractTempTable.setCanUndo- is this a bottleneck (?) how often is_hasRecordshit from this spot?
Both methods should check for transient records because they involve checking if there are any records into the table (and if any, the methods will throw an error).
#8 Updated by Alexandru Lungu over 2 years ago
I wasn't aware this could be called directly from the converted code.
#9 Updated by Dănuț Filimon over 2 years ago
Created 8196a.
#10 Updated by Dănuț Filimon over 2 years ago
- Status changed from WIP to Review
Committed 8196a/rev.14936. Removed the call to activeBuffers from AbstractTempTable._hasRecords and integrated it's functionality into the method, now only the buffers of the current table will be iterated.
#11 Updated by Alexandru Lungu over 2 years ago
I suspect the code duplicate to be quite bad architecturally.
Lets overload activeBuffers(Persistence, boolean) with activeBuffers(Persistence, boolean, Iterator<Buffer>). The first one will call by default the second one with all buffers. However, AbstractTempTable will call it only with the iterator of that table's buffers.
Please refactor.
#12 Updated by Dănuț Filimon over 2 years ago
Note that activeBuffers iterates RecordBuffer while we want to iterate Buffer instances, so those need to be casted like so: RecordBuffer next = ((BufferReference) iter.next()).buffer();. This was the main reason I did not create another method, but we can pass Iterator<RecordBuffer> as an additional parameter and prepare the Iterator beforehand.
#13 Updated by Dănuț Filimon over 2 years ago
- % Done changed from 0 to 100
Committed 8196a/rev.14937. I've created a separate method to check each buffer individually and it can be used directly by _hasRecords().
Alexandru, please review and let me know if I can go ahead with the POC performance tests.
#14 Updated by Alexandru Lungu over 2 years ago
- Status changed from Review to Internal Test
- % Done changed from 100 to 0
The changes look good to me!
Danut, you can inline isActiveBuffer by doing return <large-if-condition> && buffer.getCurrentRecord() != null;. This can be done in AbstractTempTable as well if (...isActiveBuffer() && next.getParentTable().equals(this)) return true;
Please go ahead with the testing. This requires some massive testing as we are changing the way we analyze if a temp-table is empty or not:
- test POC for performance
- test large customer application regression tests
- test large customer application
#15 Updated by Dănuț Filimon over 2 years ago
- % Done changed from 0 to 100
Alexandru Lungu wrote:
The changes look good to me!
Danut, you can inlineisActiveBufferby doingreturn <large-if-condition> && buffer.getCurrentRecord() != null;. This can be done inAbstractTempTableas wellif (...isActiveBuffer() && next.getParentTable().equals(this)) return true;
I inlined the conditions in 8196a/rev.14938 and will now begin testing.
#16 Updated by Dănuț Filimon over 2 years ago
POC regression tests passed and the results of the performance tests showed an improvement of 5.27% for the average of the last 20 runs and 0.91% for the total average.
I also did a retest on the scenario mentioned in #8196-1 and got the following results:| Counts | AbstractTempTable | BufferManager |
|---|---|---|
| Total calls | 11312 | 747 |
| Found active buffer | 0 | 994 |
| No matching persistence | 0 | 1346652 |
| No records to associate | 59758 | 1401 |
| Records associated | 0 | 994 |
- Total calls: number of calls to
AbstractTempTable._hasRecords()/BufferManager.activeBuffers(). - Found active buffer:
isActiveBuffer()returns true. - No matching persistence / No records to associate / Records associated: as before, but the counters are split based on which method is called.
#17 Updated by Alexandru Lungu over 2 years ago
This is good news. The changes are quite safe from my POV.
This is ready for merge. Greg, this is a performance improvement we need before rebasing 7156b.
#18 Updated by Greg Shah over 2 years ago
- Status changed from Internal Test to Merge Pending
8196a can merge after 8107a.
#19 Updated by Dănuț Filimon over 2 years ago
- Status changed from Merge Pending to Test
Branch 8196a was merged into trunk as rev.14961 and archived.
#20 Updated by Alexandru Lungu almost 2 years ago
This can be closed.
#21 Updated by Greg Shah almost 2 years ago
- Status changed from Test to Closed