Commit d3801e9
feat: improve transformation pipeline performance using Java 17 idioms (ExpediaGroup#665)
* feat: improve transformation pipeline performance using Java 17 idioms
- ConversionProcessorFactory: replace 12-branch if-else chain with switch
expression on class name; cache processor singletons as static constants
to eliminate per-call object allocation
- ConversionAnalyzer: replace 12-branch if-else chain in getTypeConversionFunction
with switch expression on source type name, removing redundant static imports
- ConverterImpl: use identity (==) check first before name comparison to short-circuit
same-type pass-through without string allocation
- ReflectionUtils: replace AtomicReference allocation in getRealTarget with
instanceof pattern matching; eliminate redundant isAnnotationPresent call before
getAnnotation; use instanceof pattern in getGenericClassType; use early-return
in handleReflectionException
- ClassUtils: replace stream().anyMatch() in isSpecialType/isCustomSpecialType with
plain for-loops to avoid lambda allocation on type checks; replace LinkedList with
ArrayList in getMethods for better cache locality; replace collect(toList()) with
toList() (Java 16) where result is consumed read-only; replace forEach+collect with
forEach(res::add) in getPrivateFinalFields, getPrivateFields, getMethods
- AbstractTransformer: eliminate stream+lambda in withFieldMapping and
withFieldTransformer inner loops, replacing with plain for-each
- AbstractBeanTransformer: replace asList+addAll with direct for-each add in
skipTransformationForField to avoid intermediate List allocation
- MapPopulator: replace keySet().stream().collect(toMap(...)) with entrySet()
imperative loop and pre-sized HashMap; apply instanceof pattern matching to
eliminate getClass().equals() calls in isPrimitive and getElemValue
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* config: update CHANGELOG.md for 3.0.4 performance improvements
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* feat: add JMH benchmark module for transformation pipeline
Adds bull-benchmark module with 7 microbenchmarks covering:
- mutable/immutable simple bean transformation (5 fields, setter vs constructor path)
- mutable/immutable complex bean transformation (nested objects, lists, maps)
- type conversion hot paths: int->long, String->int, Boolean->BigDecimal
Run with: java -jar bull-benchmark/target/benchmarks.jar
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* config: add benchmarks documentation to docs site
Adds docs/site/markdown/transformer/bean/benchmarks.md covering:
- what each of the 7 JMH benchmarks measures
- how to build the fat jar
- how to run (full, quick, single, with options)
- how to compare two branches with JSON output
- how to interpret Score/Error/Cnt columns
- how to add a new benchmark
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* config: add benchmark.sh convenience script and update docs
Adds benchmark.sh at the project root that builds the fat jar and runs
JMH in a single command; any arguments are forwarded to JMH.
Updates benchmarks.md to reference the script and simplify the Running
and Comparing sections.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve ClassNotFoundException and missing slf4j-api in benchmark fat jar
- Generate JMH harness sources into target/generated-sources/jmh (separate
from classes dir) then compile them in prepare-package phase so *_jmhTest
classes are present in the fat jar before shading
- Declare slf4j-api at compile scope to override the parent dependencyManagement
lock to test scope, ensuring LoggerFactory is included in the shaded jar
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* feat: add transformation-time summary table to benchmark.sh output
After JMH finishes, the script now prints a concise formatted table of
benchmark names, scores, error intervals, and units — making results
readable at a glance without scrolling through the full JMH output.
Handles both single-iteration (no error column) and multi-iteration
(± error) JMH output formats.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: suppress JDK NOTE/WARNING noise from benchmark.sh output
Redirect Maven build stdout/stderr to a temp log (only shown on failure)
and filter NOTE:/WARNING:/Processing/Writing lines from the JMH forked-JVM
output, which originate from JDK_JAVA_OPTIONS and sun.misc.Unsafe
deprecation warnings outside our control.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* feat: improve benchmark summary — ms/op, grouped sections, ± error column
- Convert scores from µs/op to ms/op for readability
- Split summary into Bean transformations and Type conversions sections
- Show ± confidence interval in Error column when available
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: address side effects from performance changes
- getNotFinalFields: wrap toList() in new ArrayList to keep the cached
list mutable, preventing UnsupportedOperationException if callers mutate it
- getRealTarget: document that empty Optional unwraps to null intentionally
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* [maven-release-plugin] prepare release 3.0.4
* [maven-release-plugin] prepare for next development iteration
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>1 parent 332d422 commit d3801e9
24 files changed
Lines changed: 821 additions & 175 deletions
File tree
- bull-bean-transformer
- src/main/java/com/expediagroup/beans
- populator
- transformer
- bull-benchmark
- src/main/java/com/expediagroup/beans/benchmark
- sample
- immutable
- mutable
- bull-bom
- bull-common
- src/main/java/com/expediagroup/transformer
- utils
- bull-converter
- src/main/java/com/expediagroup/beans/conversion
- analyzer
- processor
- bull-map-transformer
- bull-report
- docs/site/markdown/transformer/bean
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
5 | 14 | | |
6 | 15 | | |
7 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
Lines changed: 14 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
20 | 18 | | |
| 19 | + | |
21 | 20 | | |
22 | 21 | | |
23 | 22 | | |
| |||
58 | 57 | | |
59 | 58 | | |
60 | 59 | | |
61 | | - | |
62 | 60 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
71 | 68 | | |
72 | 69 | | |
73 | 70 | | |
| |||
78 | 75 | | |
79 | 76 | | |
80 | 77 | | |
81 | | - | |
| 78 | + | |
82 | 79 | | |
83 | 80 | | |
84 | 81 | | |
| |||
91 | 88 | | |
92 | 89 | | |
93 | 90 | | |
94 | | - | |
95 | 91 | | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
103 | 96 | | |
104 | | - | |
| 97 | + | |
105 | 98 | | |
106 | 99 | | |
Lines changed: 2 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
20 | 18 | | |
21 | 19 | | |
22 | 20 | | |
| |||
150 | 148 | | |
151 | 149 | | |
152 | 150 | | |
153 | | - | |
154 | | - | |
| 151 | + | |
| 152 | + | |
155 | 153 | | |
156 | 154 | | |
157 | 155 | | |
| |||
0 commit comments