Collect very slow
No edit summary
No edit summary
Line 1: Line 1:
I have at occasions been struck by extremely bad performance when it comes to the ocl Collect operator.
I have occasionally been struck by extremely bad performance when it comes to the OCL Collect operator.


After debugging I have concluded that the expression used was wrong compared to my intended usage and need.
After debugging, I concluded that the expression used was wrong compared to my intended usage and need.


Consider this expression:
Consider this expression:
  Sequence{0..7000}->collect(a| vCollectionDetails.add(Detail.Create))
  Sequence{0..7000}->collect(a| vCollectionDetails.add(Detail.Create))
My intention is to create 7000 Detail-objects and put them in the variable vCollectionDetails that has type Collection(Detail)
My intention is to create 7000 Detail-objects and put them in the variable vCollectionDetails that have type Collection(Detail).


But this expression is very (extremly) slow.
But this expression is extremely slow.


The main reason for the slowliness is that collect actually build a result of all the results of the inner expression. In our case this is a List of Lists; List of 1 detail,List of 2 details,List of 3 details...List of 6990 details etc. And this is a heavy operation as 7000 thousand lists must be created and filled with 7000*7000/2 objects - and I am not even interested in that result - I only used the Collect operator as a convenient way to act on each.
The main reason for the slowness is that Collect actually builds a result of all the results of the inner expression. In our case, this is a List of Lists; List of 1 detail, List of 2 details, List of 3 details...List of 6990 details etc. This is a heavy operation as 7000 thousand lists must be created and filled with 7000*7000/2 objects, and I am not interested in that result. I only used the Collect operator as a convenient way to act on each.


Look at [[OCLOperators foreach|foreach]] for a solution or, to avoid returning the list - and instead return something simple like this:
Look at [[OCLOperators foreach|foreach]] for a solution or to avoid returning the list. Instead, return something simple like this:
  Sequence{0..7000}->collect(a| vCollectionDetails.add(Detail.Create);0)
  Sequence{0..7000}->collect(a| vCollectionDetails.add(Detail.Create);0)
In this case the collect operator returns 1 list with 7000 zeros - very much faster than 24 million references to 7000 Detail objects.
In this case, the collect operator returns 1 list with 7000 zeros - much faster than 24 million references to 7000 Detail objects.
[[Category:OCL]]
[[Category:OCL]]

Revision as of 07:33, 27 February 2023

I have occasionally been struck by extremely bad performance when it comes to the OCL Collect operator.

After debugging, I concluded that the expression used was wrong compared to my intended usage and need.

Consider this expression:

Sequence{0..7000}->collect(a| vCollectionDetails.add(Detail.Create))

My intention is to create 7000 Detail-objects and put them in the variable vCollectionDetails that have type Collection(Detail).

But this expression is extremely slow.

The main reason for the slowness is that Collect actually builds a result of all the results of the inner expression. In our case, this is a List of Lists; List of 1 detail, List of 2 details, List of 3 details...List of 6990 details etc. This is a heavy operation as 7000 thousand lists must be created and filled with 7000*7000/2 objects, and I am not interested in that result. I only used the Collect operator as a convenient way to act on each.

Look at foreach for a solution or to avoid returning the list. Instead, return something simple like this:

Sequence{0..7000}->collect(a| vCollectionDetails.add(Detail.Create);0)

In this case, the collect operator returns 1 list with 7000 zeros - much faster than 24 million references to 7000 Detail objects.

This page was edited 98 days ago on 02/10/2024. What links here