Is it possible to disable the rebuild upon insert action? And call when needed?
|
Administrator
|
Hi Vedha,
Doing an insert will trigger a rebuild, recalculate, revalidate and refresh. Why would you like to avoid a rebuild? Does this have something to do with performance? What use case do you have in mind? Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Yes, it is because of performance issue.
I need to iterate and insert subset of elements into my instance. I perform the set of inserts in a loop, which totals to 179 inserts for the complete execution (Yes, our instance is a complex structure) on a FocusOut action. When i do this, each rebuild after insert is taking between 50ms - 100ms (from the logs). Which totals up to more than 10 seconds (75ms * 179 times). The case i explained is basic case, our loop might be needed for much more inserts. I am thinking of any option to pause the rebuild before the loop and start it after the loop is completed. So, the total time would just be less than second. |
Administrator
|
Hi Vedha,
Got it; what does the looping code looks like? Would you be able to share some pseudo-code of that loop, so we get a better idea of what it does? Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Below is how the code looks like,
<xf:action ev:event="adddetails"> <xf:setvalue ref="instance('iterator')/iterator1" value="0"/> <xf:setvalue ref="instance('iterator')/iterator2" value="7"/> <xf:action while="instance('iterator')/iterator1 <= instance('iterator')/iterator2"> <xf:action if="not(exists(rules))"> <xf:insert context="instance('core')/elements" origin="instance('part1')/*"/> <xf:insert context="instance('core')/elements/a" origin="instance('part2')/*"/> <xf:insert context="instance('core')/elements/b" origin="instance('part3')/*"/> <xf:insert context="instance('core')/element1/c" origin="instance('part4')/*"/> <xf:insert context="instance('core')/element1/d" origin="instance('part5')/*"/> <xf:insert context="instance('core')/element1/e" origin="instance('part6')/*"/> <xf:insert context="instance('core')/element1/f" origin="instance('part7')/*"/> </xf:action> </xf:action> This action is triggered on FocusOut of a UI field. |
Administrator
|
Vedha, thank you for the pseudo-code. Is the "element1" instead of "elements" a typo in the pseudo code? Are the elements a, b, c, d, e, f part of instance('part1')? Is that is the case, you could do those insertions just once in a temporary instance, reducing by a factor of 7 the number of inserts needed.
Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Thanks for the understanding. And i did the same before.
I have performed all the inserts (totally 7) into a temporary instance and then performed a final insert to the main core instance. So, for the complete loop i update the CORE instance only 8 times (One for each loop). What i saw in the logs is, even though i perform inserts into temporary instance, rebuild is called for the complete MODEL each time (7 times per loop). Because both the Core instance and the TEMP instance are in the same model. |
I am able to improve performance using below technique.
CORE instance in model 1 and one more TEMP instance in model 2. <model id="1"> <xf:instance id="CORE"> </xf:instance> </model> <model id="2"> <xf:instance id="TEMP"> </xf:instance> </model> 1) My code loops in model 1 (default). 2) used xxf:instance and xxf:variable to get the TEMP instance into a variable inside the loop. Like this <xxf:variable name="TEMP_Instance" select="xxf:instance('TEMP')"/> 3) Performed all inserts into the TEMP. 4) After the loop completes, i have inserted the TEMP instance content into CORE instance. Please help me if you have different suggestion. This is taking less than 2 seconds. |
Few more information.
The insert into TEMP instance is not causing the rebuild, i think it may be because i do not have any bind (constraints, validation) for the model 2 where the TEMP instance is resided. This is my understanding. |
Administrator
|
Vedha, indeed, doing all the inserts in a temporary variable is a good idea. Even: very good idea :). Are you seeing any rebuild at all in the log when doing this?
BTW, the rationale for the rebuild after the index is a bit involved, but let me try to explain why it is happening. Normally, rebuild/recalculate/refresh operations are "differed", i.e. are performed after your sequence of actions is completed. It is so per the XForms spec because, as you've noticed, those operations are expensive. Inserts and deletes, however, are an exception. Why? Because just after an insert, you might use the index() function, and that insert might have changed the current index for a repeat, i.e. index('my-repeat'). But if your repeat is declared as <xf:repeat bind="my-repeat">, and you have a <xf:bind id="my-repeat" ref="/my/nodes">, then for the index('my-repeat') to return the proper value, we need to reevaluate the expressions in the <xf:bind ref="…">, which happens during a rebuild… hence rebuild running right after an insert. Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
This post was updated on .
I am seeing the rebuild happening only for the final inserts which i make from the TEMP instance back to the CORE instance. I mean it is happened only few times.
Got lot of knowledge from this. Thanks for the appreciation and the explanation.. I got this completely. |
Administrator
|
Vedha, perfect then. And thank you for sharing your solution for this one with the community.
Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Free forum by Nabble | Edit this page |