We are using a multi-instance sub process for our ‘for-each’ loop kind of requirement. Please see below sample bpmn for the same.
'>
<process id="SimpleLoopForPerformance" name="SimpleLoopForPerformance" isExecutable="true"> <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent> <serviceTask id="GetRecords1" name="GetRecords1" flowable:delegateExpression="${fetchRecordServiceCall}"></serviceTask> <subProcess id="sid-A87F38F2-374D-4E89-889B-938DFB1A4603" name="subProcess" > <multiInstanceLoopCharacteristics isSequential="true" flowable:collection="EmployeeRecords"></multiInstanceLoopCharacteristics> <startEvent id="SubProcessStart" flowable:formFieldValidation="true"></startEvent> <endEvent id="SubprocessEnd"></endEvent> <serviceTask id="PrintRecords" name="PrintRecords" flowable:delegateExpression="${dummyDelegate}"></serviceTask> <sequenceFlow id="sid-9AB3C134-DF0C-4C9B-9CEB-A825EFC5C1BB" sourceRef="SubProcessStart" targetRef="PrintRecords"></sequenceFlow> <sequenceFlow id="sid-A0C7F764-9492-45E6-AF0B-8DD17DF27BFB" sourceRef="PrintRecords" targetRef="SubprocessEnd"></sequenceFlow> </subProcess> <endEvent id="sid-DDD4504F-E6EF-44C2-9783-3E9072DE12EB"></endEvent> <sequenceFlow id="sid-2F691C36-418C-4C6A-A11A-770E569349A1" sourceRef="sid-A87F38F2-374D-4E89-889B-938DFB1A4603" targetRef="sid-DDD4504F-E6EF-44C2-9783-3E9072DE12EB"></sequenceFlow> <sequenceFlow id="sid-4220E4E7-11DC-4A17-BA1F-0C1A8D79207A" sourceRef="GetRecords1" targetRef="sid-A87F38F2-374D-4E89-889B-938DFB1A4603"></sequenceFlow> <sequenceFlow id="sid-645E0593-97E3-4696-983D-3375D95624B0" sourceRef="startEvent1" targetRef="GetRecords1"></sequenceFlow>
-
In Get Records task we are creating dummy records as per configured input and set as process collection variable EmployeeRecords.
-
Inside the loop I am using a single delegate task -‘DummyDelegate’ which is printing after every 1000 subprocess instance processing.
int count = (int) execution.getVariable(“loopCounter”);
if(count % 1000 == 0) {
LOG.info(“**loopCounter=” + count + " , " + (System.currentTimeMillis()) / 1000);
}
When we execute the workflow we are getting below log.
2021-02-20 11:13:18.812 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==0 , 1613799798
2021-02-20 11:13:25.168 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==1000 , 1613799805
2021-02-20 11:13:34.187 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==2000 , 1613799814
2021-02-20 11:13:48.058 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==3000 , 1613799828
2021-02-20 11:14:09.013 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==4000 , 1613799849
2021-02-20 11:14:41.461 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==5000 , 1613799881
2021-02-20 11:15:22.205 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==6000 , 1613799922
2021-02-20 11:16:11.106 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==7000 , 1613799971
2021-02-20 11:17:11.337 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==8000 , 1613800031
2021-02-20 11:18:24.506 INFO 2960 — [nio-8999-exec-2] c.s.flowable.delegates.SapperAction : **loopCounter==9000 , 1613800104
As you can see, the execution time per 1000 records is consistently increasing. Many times it is almost 100% increase.
for first 100 records it is 7 sec, next 1000 it is 9, then 14 , 21 , 32 …ad from 8000 to 9000 it is 73 seconds.
We are not sure why this performance degradation.
Any pointers ?
Any suggestions to improve this performance ?