[ 
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)

Reply via email to