[
https://issues.apache.org/jira/browse/CAMEL-25963?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18130234#comment-18130234
]
Aurélien Pupier commented on CAMEL-25963:
-----------------------------------------
crazy first investigation with IBM Bob:
What I measured
I used plain javac with -proc:none, on JDK 25.
Compiled Time
All 88 files about 24 s
All files except MimeTypeHelper about 18.5 s
Each file on its own (all except ArtifactUtils) about 0.7 s, mostly JVM start-up
ArtifactUtils.java on its own 21.4 s
MimeTypeHelper has a switch with about 1000 cases. It costs only about 5 s of
the total, so it is a minor factor.
Why ArtifactUtils is slow
The file has four huge tables, COMPONENTS, LANGUAGES, DATAFORMATS and BEANS.
The first has about 420 entries. They are written like this:
Map.ofEntries(
Map.entry("a2a", "camel-a2a"),
Map.entry("activemq", "camel-activemq"), ...
Map.ofEntries(Entry<? extends K, ? extends V>...) and Map.entry(K, V) are both
generic methods. Each Map.entry(...) argument is a generic method call that
javac must type-infer together with the outer call. That inference work grows
much faster than linearly with the number of arguments.
I reproduced this in isolation, with the same pattern and synthetic keys:
Entries Map.ofEntries(Map.entry…) Array of strings plus a loop
100 0.8 s 0.3 s
200 2.6 s 0.3 s
400 17.5 s 0.3 s
Doubling the entries from 200 to 400 multiplies the time by about 7. The array
form stays flat.
This has probably got worse as the generated tables grew with each new
component. The git log shows commits that added to them, for example the wasm
removal and the Citrus, OpenFeature and Kafka share components.
How to find slow classes yourself
Time each file separately. This is what found it:
cd core/camel-util
CP=$(find ~/.m2 -name 'slf4j-api-2*.jar' | head -1)
for f in $(find src/main/java -name '*.java'); do
s=$(date +%s.%N)
javac -proc:none -d /tmp/out -cp "$CP" -sourcepath src/main/java $f
>/dev/null 2>&1
echo "$(echo "$(date +%s.%N) - $s" | bc) $f"
done | sort -rn | head
Anything far above the roughly 0.7 s JVM start-up baseline is a suspect.
Bisect. Compile everything except the suspect, as I did with MimeTypeHelper. If
the total barely changes, it is not the cause.
Take thread dumps during a slow build. Run jstack <pid> a few times on the
javac or Maven process. The repeated com.sun.tools.javac.comp.Infer,
DeferredAttr or Resolve frames point at generic or lambda inference. A profiler
such as async-profiler gives the same information.
Check the profiles. The nullcheck profile in parent/pom.xml forks javac and
adds Error Prone and NullAway, which slows every module. If you built with it,
rule it out first. Annotation processors add time too, which is why I used
-proc:none.
Fix
Replace the Map.ofEntries(Map.entry(...), ...) pattern with a form that needs
no nested generic inference. For example, use a flat String[] of key/value
pairs filled into a map in a static {} block. Because the table is generated,
the change belongs in the generator, not in the file's COMPONENTS: START
blocks, which say "do NOT edit". I have not yet found which build tool writes
it.
The same pattern may appear in other generated tables, such as SensitiveUtils,
which the Javadoc mentions as the model. They are worth a quick per-file timing
check too.
I haven't changed any code. I can locate the generator and make the change if
you want.
> Investigate compile and recompile time of camel util
> ----------------------------------------------------
>
> Key: CAMEL-25963
> URL: https://issues.apache.org/jira/browse/CAMEL-25963
> Project: Camel
> Issue Type: Task
> Components: camel-util
> Affects Versions: 4.24.0
> Reporter: Aurélien Pupier
> Priority: Minor
>
> camel-util compile/recompile is part of the critical path for parallel
> builds. It is taking 2 times 39 seconds, it is strange that it takes so much
> time as no Java code is generated (so recompile might be useless?) and also
> there are only 87 classes, 39 seconds to compile them seems a lot
> https://develocity.apache.org/s/7mkwa3uanbtie/timeline?details=v3fqci3hrxtzy&end=1792654076711&page=2&sort=execution&start=1792653568985
> https://develocity.apache.org/s/7mkwa3uanbtie/timeline?details=wmvchkusjznpu&end=1792654076711&page=6&sort=execution&start=1792653568985
> seems the recompile is doe for absolutely all modules, i'm wondering if it
> should notbe part only when there is some Java code generated.
> https://issues.apache.org/jira/browse/CAMEL-14628
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)