1 # Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. 2 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 # 4 # This code is free software; you can redistribute it and/or modify it 5 # under the terms of the GNU General Public License version 2 only, as 6 # published by the Free Software Foundation. 7 # 8 # This code is distributed in the hope that it will be useful, but WITHOUT 9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 # version 2 for more details (a copy is included in the LICENSE file that 12 # accompanied this code). 13 # 14 # You should have received a copy of the GNU General Public License version 15 # 2 along with this work; if not, write to the Free Software Foundation, 16 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 # 18 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 # or visit www.oracle.com if you need additional information or have any 20 # questions. 21 22 #=============================================================================== 23 # Leyden-premain + spring-petclinic demo (https://github.com/spring-projects/spring-petclinic) 24 # 25 # Build spring-petclinic: 26 # make app 27 # 28 # Build all leyden optimization artifacts (this is using the older "4 step training run" which will be simplified): 29 # make aot 30 # 31 # Run with Leyden optimizations 32 # make run 33 # 34 # Run without Leyden optimizations 35 # make run0 36 37 # Set the following to point to youd "Build JDK", your JDK mainline build, and your Leyden JDK build. 38 # 39 # *** NOTE: JDK 21 (or 17) is needed to build spring-petclinic-3.2.0-SNAPSHOT.jar 40 BLDJDK_HOME = /jdk3/official/jdk21 41 42 # Points to your build with https://github.com/openjdk/jdk 43 # For comparison purposes, this build should be the latest version of the mainline that 44 # has been merged into https://github.com/openjdk/leyden/tree/premain 45 MAINLINE_HOME = /jdk3/bld/rum/images/jdk 46 47 # Points to your build with https://github.com/openjdk/leyden/tree/premain 48 PREMAIN_HOME = /jdk3/bld/le4/images/jdk 49 #=============================================================================== 50 51 LOG_INIT = -Xlog:init 52 53 # Options passed to PREMAIN_JAVA. See compare_premain_builds below 54 PM_OPTS = 55 56 # Usually there's no need to change the following 57 JAR_CMD = ${BLDJDK_HOME}/bin/jar 58 JAVAC_CMD = ${BLDJDK_HOME}/bin/javac 59 BLDJDK_JAVA = ${BLDJDK_HOME}/bin/java 60 MAINLINE_JAVA = ${MAINLINE_HOME}/bin/java 61 PREMAIN_JAVA = ${PREMAIN_HOME}/bin/java ${PM_OPTS} 62 PC_REPO = petclinic-snapshot 63 PC_JAVA_SOURCES = ${PC_REPO}/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java 64 PC_APP_JAR = ${PC_REPO}/target/spring-petclinic-3.2.0-SNAPSHOT.jar 65 PC_APP_UNPACKED = ${PC_REPO}/target/unpacked 66 67 # This is for uploading to artifactory, to be tested with 68 # ../../runtime/cds/appcds/leyden/SpringPetClinic.java 69 PC_APP_UNPACKED_ZIP = ${PC_REPO}/target/spring-petclinic-3.2.0.zip 70 71 PC_MAIN_CLASS = org.springframework.samples.petclinic.PetClinicApplication 72 73 # Note: you can add specify PM_VER (PreMain Version) for comparing the performance of different builds of premain. 74 # See the compare_premain_builds target below 75 76 # old workflow 77 PC_CLASSLIST = spring-petclinic$(PM_VER).classlist 78 PC_STATIC_JSA = spring-petclinic$(PM_VER).static.jsa 79 PC_DYNAMIC_JSA = spring-petclinic$(PM_VER).dynamic.jsa 80 PC_CACHED_CODE = spring-petclinic$(PM_VER).code.jsa 81 82 # new workflow 83 PC_CDS_PREIMAGE = spring-petclinic$(PM_VER).cds.preimage 84 PC_CDS = spring-petclinic$(PM_VER).cds 85 86 # TODO: should we add -Dspring.context.exit=onRefresh to command line?? 87 # This will make the JVM quit after printing this line: 88 # 89 # 4:21.639 ... o.s.b.a.e.web.EndpointLinksResolver : Exposing 13 endpoint(s) beneath base path '/actuator' 90 # 91 # Whereas -DautoQuit=true will make it exit after printing the following (a little bit of application code is executed) 92 # 93 # 4:21.665 ... o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '' 94 # 4:21.666 ... o.s.s.petclinic.PetClinicApplication : Started PetClinicApplication in 1.358 seconds (process running for 1.584) 95 # #### Booted and returned in 1453ms 96 # 4:21.692 ... j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 97 # 4:21.693 ... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 98 # 4:21.694 ... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 99 HEAP_SIZE = -Xmx2g 100 UNPACKED_CMDLINE = $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath -DautoQuit=true -Dspring.aot.enabled=true -Dspring.output.ansi.enabled=NEVER ${PC_MAIN_CLASS} 101 DUMMY_CMDLINE = $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath.dummy Dummy 102 103 all: check git app aot 104 105 check: 106 @if ${PREMAIN_JAVA} -XX:+PrintFlagsFinal --version | grep -q ArchiveInvokeDynamic; then \ 107 true; \ 108 else \ 109 echo PREMAIN_HOME should point to your build of https://github.com/openjdk/leyden/tree/premain; \ 110 exit 1; \ 111 fi 112 113 # A bunch of quick targets so you can type "make list" to create the classlist, etc 114 git: ${PC_JAVA_SOURCES} 115 app: ${PC_APP_JAR} 116 unpack: ${PC_APP_UNPACKED} 117 118 # The "4 step training run" workflow -- this will soon be replaced with the new workflow in ../javac_new_workflow/ 119 list: ${PC_CLASSLIST} 120 static: ${PC_STATIC_JSA} 121 dynamic: ${PC_DYNAMIC_JSA} 122 aot: ${PC_CACHED_CODE} 123 124 # Check out this specific version of spring-petclinic that we have been testing with. 125 # https://github.com/spring-projects/spring-petclinic/commit/80fd11067c4662486e4c635deceba927375b621c 126 # Author: Dave Syer <dsyer@vmware.com> 127 # Date: Wed Jan 10 05:01:00 2024 128 # Upgrade to Boot 3.2.1 129 ${PC_JAVA_SOURCES}: 130 rm -rf ${PC_REPO} 131 git clone https://github.com/spring-projects/spring-petclinic ${PC_REPO} 132 cd ${PC_REPO}; git reset --hard 80fd11067c4662486e4c635deceba927375b621c 133 cd ${PC_REPO}; git apply ../premain-patch.diff 134 135 # Need to touch ${PC_APP_JAR} as mvn wants to set it the release date of 3.2.0-SNAPSHOT 136 ${PC_APP_JAR}: ${PC_JAVA_SOURCES} 137 cd ${PC_REPO}; JAVA_HOME=${BLDJDK_HOME} mvn -Dmaven.test.skip=true package 138 if test -f ${PC_APP_JAR}; then \ 139 touch ${PC_APP_JAR}; \ 140 fi 141 142 ${PC_APP_UNPACKED}: ${PC_APP_JAR} 143 rm -rf ${PC_APP_UNPACKED} 144 mkdir -p ${PC_APP_UNPACKED} 145 cd ${PC_APP_UNPACKED} && \ 146 ${JAR_CMD} xf ../spring-petclinic-3.2.0-SNAPSHOT.jar && \ 147 ${JAR_CMD} cf classes.jar META-INF org && \ 148 cd BOOT-INF/classes/ && \ 149 ${JAR_CMD} cf classes.jar * 150 echo ${PC_APP_UNPACKED}/classes.jar $$(find ${PC_APP_UNPACKED}/BOOT-INF -name \*.jar | sort) \ 151 | sed -e 's/ /:/g' > ${PC_APP_UNPACKED}/classpath 152 echo $$(cat ${PC_APP_UNPACKED}/classpath):Dummy.jar > ${PC_APP_UNPACKED}/classpath.dummy 153 ${JAR_CMD} cf0 ${PC_APP_UNPACKED_ZIP} ${PC_APP_UNPACKED} 154 $(MAKE) runb 155 156 #uncomment this to see the generated classes for dynamic proxies 157 #SAVE_GEN_FILES=-Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true 158 159 ${PC_CLASSLIST}: ${PC_APP_UNPACKED} 160 ${PREMAIN_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_CLASSLIST} \ 161 -Xlog:class+load=debug:file=${PC_CLASSLIST}.classload.log ${SAVE_GEN_FILES} \ 162 ${UNPACKED_CMDLINE} 163 wc -lc ${PC_CLASSLIST} 164 165 ${PC_STATIC_JSA}: ${PC_CLASSLIST} 166 rm -f ${PC_STATIC_JSA}.log 167 ${PREMAIN_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_CLASSLIST} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \ 168 -XX:SharedArchiveFile=${PC_STATIC_JSA} \ 169 -XX:+PreloadSharedClasses -XX:+ArchiveInvokeDynamic -XX:+ArchiveDynamicProxies -XX:+ArchiveReflectionData \ 170 -XX:+ArchiveLoaderLookupCache -Dleyden.debug.archived.packages=1 \ 171 -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=${PC_STATIC_JSA}.log 172 ls -l ${PC_STATIC_JSA} 173 174 ${PC_DYNAMIC_JSA}: ${PC_STATIC_JSA} 175 rm -f ${PC_DYNAMIC_JSA} ${PC_DYNAMIC_JSA}.log 176 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_JSA} \ 177 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=${PC_DYNAMIC_JSA}.log \ 178 -XX:+RecordTraining ${UNPACKED_CMDLINE} 179 ls -l ${PC_DYNAMIC_JSA} 180 181 ${PC_CACHED_CODE}: ${PC_DYNAMIC_JSA} 182 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_JSA} -XX:+ReplayTraining -XX:+StoreCachedCode \ 183 -XX:CachedCodeFile=${PC_CACHED_CODE} -XX:CachedCodeMaxSize=512M ${UNPACKED_CMDLINE} 184 ls -l ${PC_CACHED_CODE} 185 186 # run with premain optimizatipn 187 run: ${PC_CACHED_CODE} 188 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_JSA} -XX:+ReplayTraining -XX:+LoadCachedCode \ 189 -XX:CachedCodeFile=${PC_CACHED_CODE} ${LOG_INIT} -Xlog:scc=error ${UNPACKED_CMDLINE} 190 191 # run with just static CDS archive 192 runs: ${PC_STATIC_JSA} 193 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} ${LOG_INIT} ${UNPACKED_CMDLINE} 194 195 # run with just static CDS archive, but instead of the main class, give a fake class name 196 # Because -XX:+LoadSharedClasses is specified, this command will basically test the speed of loading all 197 # the classes and entering the main() method. 198 dummy: ${PC_STATIC_JSA} Dummy.jar 199 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} ${LOG_INIT} ${DUMMY_CMDLINE} 200 201 dummy-50: ${PC_STATIC_JSA} Dummy.jar 202 bash -c "time for i in {1..50}; do ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} ${DUMMY_CMDLINE}; done" 203 204 dummy-50-perf: ${PC_STATIC_JSA} Dummy.jar 205 perf stat -r 50 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} ${DUMMY_CMDLINE} 206 207 Dummy.jar: Dummy.java 208 ${JAVAC_CMD} Dummy.java 209 ${JAR_CMD} cf Dummy.jar Dummy*.class 210 211 # run with just dynamic CDS archive 212 rund: ${PC_DYNAMIC_JSA} 213 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_JSA} \ 214 ${LOG_INIT} ${UNPACKED_CMDLINE} 215 216 # run WITHOUT premain optimizatipn 217 run0: ${PC_APP_UNPACKED} 218 ${PREMAIN_JAVA} ${LOG_INIT} ${UNPACKED_CMDLINE} 219 220 # Run using "build JDK" 221 runb: ${PC_APP_UNPACKED} 222 ${BLDJDK_JAVA} ${UNPACKED_CMDLINE} 223 224 # Running with mainline 225 PC_CLASSLIST_MAINLINE = spring-petclinic.ml.classlist 226 PC_STATIC_JSA_MAINLINE = spring-petclinic.static.ml.jsa 227 228 list.ml: ${PC_CLASSLIST_MAINLINE} 229 230 static.ml: ${PC_STATIC_JSA_MAINLINE} 231 232 ${PC_CLASSLIST_MAINLINE}: ${PC_APP_UNPACKED} 233 ${MAINLINE_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_CLASSLIST_MAINLINE} \ 234 -Xlog:class+load=debug:file=spring-petclinic.classload.ml.log \ 235 ${UNPACKED_CMDLINE} 236 wc -lc ${PC_CLASSLIST_MAINLINE} 237 238 ${PC_STATIC_JSA_MAINLINE}: ${PC_CLASSLIST_MAINLINE} 239 rm -f ${PC_STATIC_JSA_MAINLINE}.log 240 ${MAINLINE_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_CLASSLIST_MAINLINE} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \ 241 -XX:SharedArchiveFile=${PC_STATIC_JSA_MAINLINE} \ 242 -Xlog:cds=debug,cds+class=debug,cds+heap=warning:file=${PC_STATIC_JSA_MAINLINE}.log 243 ls -l ${PC_STATIC_JSA_MAINLINE} 244 245 run0.ml: ${PC_STATIC_JSA_MAINLINE} 246 ${MAINLINE_JAVA} \ 247 ${UNPACKED_CMDLINE} 248 249 runs.ml: ${PC_STATIC_JSA_MAINLINE} 250 ${MAINLINE_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA_MAINLINE} \ 251 ${UNPACKED_CMDLINE} 252 253 clean.ml: 254 rm -fv ${PC_CLASSLIST_MAINLINE}* ${PC_STATIC_JSA_MAINLINE}* 255 256 #======================================== new workflow 257 pre: ${PC_CDS_PREIMAGE} 258 cds: ${PC_CDS} 259 260 ${PC_CDS_PREIMAGE}: ${PC_APP_UNPACKED} 261 rm -f ${PC_CDS_PREIMAGE} ${PC_CDS} 262 ${PREMAIN_JAVA} -XX:+PreloadSharedClasses \ 263 -XX:+ArchiveInvokeDynamic -XX:+ArchiveReflectionData \ 264 -XX:+ArchiveDynamicProxies -XX:+ArchiveLoaderLookupCache -XX:CachedCodeMaxSize=512M \ 265 -XX:+UnlockDiagnosticVMOptions -XX:+CDSManualFinalImage -XX:CacheDataStore=${PC_CDS} \ 266 -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=${PC_CDS_PREIMAGE}.log \ 267 ${UNPACKED_CMDLINE} 268 ls -l ${PC_CDS_PREIMAGE} 269 270 ${PC_CDS}: ${PC_CDS_PREIMAGE} 271 rm -f ${PC_CDS} 272 ${PREMAIN_JAVA} -XX:+PreloadSharedClasses -XX:+ArchiveInvokeDynamic -XX:CachedCodeMaxSize=512M \ 273 -XX:+UnlockDiagnosticVMOptions -XX:CDSPreimage=${PC_CDS_PREIMAGE} -XX:CacheDataStore=${PC_CDS} \ 274 -Xlog:scc,cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=${PC_CDS}.log \ 275 -Dleyden.debug.archived.packages=1 \ 276 ${UNPACKED_CMDLINE} 277 ls -l ${PC_CDS} 278 ls -l ${PC_CDS}.code 279 280 # run with NEW workflow 281 runn: ${PC_CDS} 282 ${PREMAIN_JAVA} -XX:CacheDataStore=${PC_CDS} ${LOG_INIT} -Xlog:scc=error ${UNPACKED_CMDLINE} 283 284 # see dummy above 285 dummyn: ${PC_CDS} Dummy.jar 286 ${PREMAIN_JAVA} -XX:CacheDataStore=${PC_CDS} ${LOG_INIT} -Xlog:scc=error ${DUMMY_CMDLINE} 287 288 dummyn-50: ${PC_CDS} Dummy.jar 289 bash -c "time for i in {1..50}; do ${PREMAIN_JAVA} -XX:CacheDataStore=${PC_CDS} \ 290 -XX:-ReplayTraining -XX:-LoadCachedCode -Xlog:scc=error ${DUMMY_CMDLINE}; done" 291 292 dummyn-50-perf: ${PC_CDS} Dummy.jar 293 perf stat -r 50 ${PREMAIN_JAVA} -XX:CacheDataStore=${PC_CDS} -XX:-ReplayTraining -XX:-LoadCachedCode -Xlog:scc=error ${DUMMY_CMDLINE} 294 295 clean: clean0 296 rm -rf *~ ${PC_REPO} Dummy*.class Dummy.jar *.old.txt *.new.txt tmp.txt hs_err* 297 298 # clean the the leyden artifacts 299 clean0: 300 rm -fv spring-petclinic.* 301 302 # clean the the leyden artifacts for the new workflow only 303 cleann: 304 rm -fv spring-petclinic.cds.* 305 306 include ../lib/Bench.gmk 307 308 # Same as mainline_vs_premain in ../lib/Bench.gmk, but also includes old workflow 309 mainline_vs_premain_all: clean0 _mainline_vs_premain_all 310 311 _mainline_vs_premain_all: 312 @echo "run,mainline default,mainline custom static CDS,premain custom static CDS,premain custom static CDS+training+AOT,premain new workflow" 313 @first=1; for i in ${LOOPS}; do \ 314 rm -f tmp.txt; \ 315 $(SLEEP) $(MAKE) LOG_INIT= run0.ml | grep Booted >> tmp.txt; \ 316 $(SLEEP) $(MAKE) LOG_INIT= runs.ml | grep Booted >> tmp.txt; \ 317 $(SLEEP) $(MAKE) LOG_INIT= runs | grep Booted >> tmp.txt; \ 318 $(SLEEP) $(MAKE) LOG_INIT= run | grep Booted >> tmp.txt; \ 319 $(SLEEP) $(MAKE) LOG_INIT= runn | grep Booted >> tmp.txt; \ 320 if test "$$first" != "1"; then \ 321 echo $$i$$(cat tmp.txt | sed -e 's/.*in /,/g' -e 's/ms//g') | sed -e 's/ //g'; \ 322 fi; \ 323 first=0; \ 324 done 325 326 # Same as compare_premain_builds in ../lib/Bench.gmk, but compare CDS only, and old workflow as well 327 328 compare_premain_builds_full: clean0 _compare_premain_builds_full 329 330 _compare_premain_builds_full: 331 @echo Old build = ${PM_OLD} with options ${PM_OPTS_OLD} 332 @echo New build = ${PM_NEW} with options ${PM_OPTS_NEW} 333 @echo "Run,Old static CDS only,New static CDS only,Old static CDS + training + AOT,New static CDS + training + AOT,Old 1-step training,New 1-step training" 334 @first=1; for i in ${LOOPS}; do \ 335 rm -f tmp.txt; \ 336 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_OLD} PM_VER=.old PM_OPTS="${PM_OPTS_OLD}" runs | grep Booted >> tmp.txt; \ 337 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_NEW} PM_VER=.new PM_OPTS="${PM_OPTS_NEW}" runs | grep Booted >> tmp.txt; \ 338 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_OLD} PM_VER=.old PM_OPTS="${PM_OPTS_OLD}" run | grep Booted >> tmp.txt; \ 339 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_NEW} PM_VER=.new PM_OPTS="${PM_OPTS_NEW}" run | grep Booted >> tmp.txt; \ 340 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_OLD} PM_VER=.old PM_OPTS="${PM_OPTS_OLD}" runn | grep Booted >> tmp.txt; \ 341 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_NEW} PM_VER=.new PM_OPTS="${PM_OPTS_NEW}" runn | grep Booted >> tmp.txt; \ 342 if test "$$first" != "1"; then \ 343 echo $$i$$(cat tmp.txt | sed -e 's/.*in /,/g' -e 's/ms//g') | sed -e 's/ //g'; \ 344 fi; \ 345 first=0; \ 346 done 347 348 # same as above, but only compare the speed of "make runs" 349 compare_premain_builds_static: clean0 _compare_premain_builds_static 350 351 _compare_premain_builds_static: 352 @echo Old build = ${PM_OLD} with options ${PM_OPTS_OLD} 353 @echo New build = ${PM_NEW} with options ${PM_OPTS_NEW} 354 @echo "Run,Old static CDS only,New static CDS only" 355 @first=1; for i in ${LOOPS}; do \ 356 rm -f tmp.txt; \ 357 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_OLD} PM_VER=.old PM_OPTS="${PM_OPTS_OLD}" runs | grep Booted >> tmp.txt; \ 358 $(SLEEP) $(MAKE) LOG_INIT= PREMAIN_HOME=${PM_NEW} PM_VER=.new PM_OPTS="${PM_OPTS_NEW}" runs | grep Booted >> tmp.txt; \ 359 if test "$$first" != "1"; then \ 360 echo $$i$$(cat tmp.txt | sed -e 's/.*in /,/g' -e 's/ms//g') | sed -e 's/ //g'; \ 361 fi; \ 362 first=0; \ 363 done 364 365 # Clean up the logs generated by compare_premain_builds, so you can see if one build includes 366 # more classes than another. 367 diff_training_logs: 368 @for i in old new; do \ 369 grep cds,class spring-petclinic.$$i.static.jsa.log | \ 370 sed -e 's/.*0x[0-9a-f]* ..... //g' \ 371 -e 's/Lambda\/0x[0-9a-f]*/Lambda\/nnn/g' \ 372 -e 's/MH\/0x[0-9a-f]*/MH\/nnn/g' | \ 373 sort > old-workflow-static-classes.$$i.txt; \ 374 grep cds,class spring-petclinic.$$i.dynamic.jsa.log | \ 375 sed -e 's/.*0x[0-9a-f]* ..... //g' \ 376 -e 's/Lambda\/0x[0-9a-f]*/Lambda\/nnn/g' \ 377 -e 's/MH\/0x[0-9a-f]*/MH\/nnn/g' | \ 378 sort > old-workflow-dynamic-classes.$$i.txt; \ 379 grep cds,class spring-petclinic.$$i.cds.log | \ 380 sed -e 's/.*0x[0-9a-f]* ..... //g' \ 381 -e 's/Lambda\/0x[0-9a-f]*/Lambda\/nnn/g' \ 382 -e 's/MH\/0x[0-9a-f]*/MH\/nnn/g' | \ 383 sort > new-workflow-classes.$$i.txt; \ 384 done 385 @ls -l *.old.txt *.new.txt 386 @echo '***' 387 @echo "You can diff the above files to diagnose speed differences between two builds" 388 389