Invoke Workflow in For Each Row Slower than Nested Ifs

Hello,

I have a sequence which loops through a large data table (up to 100k rows) with a For Each Row.

There is an extensive logic within the ForEach, which I initially designed with multiple Nested Ifs.

For ease of reading I decided to move it to a workflow, however the workflow is taking much longer to run than nested ifs. It takes 14 seconds for a 71.5K row data table using nested Ifs, but I had to stop the process after 15 minutes with invoking a workflow when it still hasn’t finished at that point.The workflow works with a smaller set of data.

I have read here and here, but the suggestions did not improve the performance.

Please can anybody suggest whether this is something expected, or I’ve made a mistake somewhere. I tried removing the TryCatch, any extra arguments. Yet the workflow completed with a smaller set of data, therefore I am happy that it works.


image

Rather than invoking the workflow, have you tried putting the workflow directly into the for each?

I say this as I assume the invoking each time is causing the slowness

Very good point, thank you. Our company best practice indicates splitting a process into separate .xaml files to increase reusability and readability, but I’ve never had to invoke a workflow within a ForEachRow until now, all very interesting.

I’ve just tried the workflow directly and it worked in 14 seconds as well, I’m just surprised the invocation would actually take that long! So it is purely down to the fact that the process has to refer to a separate invoked file that the time increases so drastically? Or is there any other explanation?

It’s normally the passing of data in an invoke multiple times i believe.

We had a similar issue where we also split our XAMLs for the same reasons but due to efficiency it was just better to have the workflow at the higher level as we were passing larger datatables.

Another thing to try which might help abit is to use a Paralell For Each Loop with the Datatable.

You can try: ForEach row in DtOATransaction.AsEnumerable() with TypeArgument as Datarow

I realize this is old, but for anyone having issues with invoke workflow in loops there seems to be some JIT (just in time) compilation performance hit whenever we invoke workflows. Avoiding “invoke workflow” in For Each loops that process high volumes is the best route i’ve found in processes.

However in libraries you can just select the “Ready to Run” checkbox during publish. With just this change alone my activity when from taking ~ 5 seconds to process a request to less than a second.

RtR

So another solution to having this issue in processes could be to put your looping logic inside a library with Ready to Run and then import that library to your main project.

  • Ready to Run - set to Yes to optimize the generated assemblies for faster JIT compilation at runtime. Available for Windows - legacy libraries only.

I wonder why Ready to Run isn’t an option for process publishing? Or some better optimization around invoking workflows so developers are encouraged to make their code modular to avoid deep nesting.

1 Like