On 09.05.22 22:13, MG wrote:
Hi Jochen,
our code certainly creates a lot of (short lived) class instances*, but
we do not dynamically create new classes, so the overhead of creating
the initial Indy callsites should only be incurred once at the
beginning, and then should no longer play a role. So if the same SQL
creation code is executed in a loop as in the sample script I provided,
each loop after the first should be as fast as non-Indy Groovy, no ?
You pay the cost every time the callsite gets invalidated. If you do
def getMeta(table, column) {
table.getMetaData(column)
}
getMeta(PERSON, PERSON_NAME)
getMeta(PERSON, PERSON_STREET)
class PERSON extends Table {
...
class PERSON_NAME extends Column {...}
class PERSON_STREET extends Column {...}
...
}
then you have 3 callsites, but 4 inits, since the callsite in getMeta
will be invalidated for the change from PERSON_NAME to PERSON_STREET.
And if you do
10.times {
getMeta(PERSON, PERSON_NAME)
getMeta(PERSON, PERSON_STREET)
}
you get 20 callsite inits plus 19 callsite invalidations in getMetaClass.
Even with caching.. in the current implementation we check only on the
receiver, but here an argument is changing.
If I rerun my test with 1 classes a 1 method and let this run for 500k
times then I get
Groovy 4 indy: 68-73
Groovy 3 non-indy: 90-101
Of course the less iterations the worse for indy:
Groovy 4
1k: 1215
10k: 231
100k: 105
1m: 70
Groovy 3
1k: 780-1000
10k: 169
100k: 96
1m: 90
each run involves running the code 10 times, then measuring 10 times to
really really trying to exclude any initial costs. And from that
perspective Groovy 4 indy is better.
Do you think that a Groovy feature such as e.g. traits could be
responsible for the constant need for callsite creation ? A less-used
Groovy feature such as traits, that we use only in certain, more complex
scenarios, being responsible might explain why the performance problems
a) occur only in more complex test cases, and b) up to date no other
project seems to suffer the same problem as we do...
[...]
I do not remember anymore how they are compiled - but from what I
remember I think there is a level of indirection involved, just don't
remember if that call is in dynamic or static. If the first, then it
might be
bye Jochen