1 /* 2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.openjdk.jmh.runner.options; 26 27 import joptsimple.OptionException; 28 import joptsimple.OptionParser; 29 import joptsimple.OptionSet; 30 import joptsimple.OptionSpec; 31 import org.openjdk.jmh.annotations.Mode; 32 import org.openjdk.jmh.annotations.Threads; 33 import org.openjdk.jmh.profile.Profiler; 34 import org.openjdk.jmh.profile.ProfilerFactory; 35 import org.openjdk.jmh.results.format.ResultFormatType; 36 import org.openjdk.jmh.util.HashMultimap; 37 import org.openjdk.jmh.util.Multimap; 38 import org.openjdk.jmh.util.Optional; 39 40 import java.io.IOException; 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.Collection; 44 import java.util.HashSet; 45 import java.util.List; 46 import java.util.Set; 47 import java.util.concurrent.TimeUnit; 48 49 /** 50 * Class that handles all the command line options. 51 */ 52 public class CommandLineOptions implements Options { 53 private static final long serialVersionUID = 5565183446360224399L; 54 55 private final Optional<Integer> iterations; 56 private final Optional<TimeValue> timeout; 57 private final Optional<TimeValue> runTime; 58 private final Optional<Integer> batchSize; 59 private final Optional<Integer> warmupIterations; 60 private final Optional<TimeValue> warmupTime; 61 private final Optional<Integer> warmupBatchSize; 62 private final List<Mode> benchMode = new ArrayList<Mode>(); 63 private final Optional<Integer> threads; 64 private final List<Integer> threadGroups = new ArrayList<Integer>(); 65 private final Optional<Boolean> synchIterations; 66 private final Optional<Boolean> gcEachIteration; 67 private final Optional<VerboseMode> verbose; 68 private final Optional<Boolean> failOnError; 69 private final Set<Class<? extends Profiler>> profilers = new HashSet<Class<? extends Profiler>>(); 70 private final Optional<TimeUnit> timeUnit; 71 private final Optional<Integer> opsPerInvocation; 72 private final List<String> regexps = new ArrayList<String>(); 73 private final Optional<Integer> fork; 74 private final Optional<Integer> warmupFork; 75 private final Optional<String> output; 76 private final Optional<String> result; 77 private final Optional<ResultFormatType> resultFormat; 78 private final Optional<String> jvm; 79 private final Optional<Collection<String>> jvmArgs; 80 private final Optional<Collection<String>> jvmArgsAppend; 81 private final Optional<Collection<String>> jvmArgsPrepend; 82 private final List<String> excludes = new ArrayList<String>(); 83 private final Optional<WarmupMode> warmupMode; 84 private final List<String> warmupMicros = new ArrayList<String>(); 85 private final Multimap<String, String> params = new HashMultimap<String, String>(); 86 private final boolean list; 87 private final boolean listResultFormats; 88 private final boolean help; 89 private final boolean listProfilers; 90 91 private final transient OptionParser parser; 92 93 /** 94 * Parses the given command line. 95 * @param argv argument list 96 * @throws CommandLineOptionException if some options are misspelled 97 */ 98 public CommandLineOptions(String... argv) throws CommandLineOptionException { 99 parser = new OptionParser(); 100 parser.formatHelpWith(new OptionFormatter()); 101 102 OptionSpec<Integer> optMeasureCount = parser.accepts("i", "Number of measurement iterations to do.") 103 .withRequiredArg().ofType(Integer.class).describedAs("int"); 104 105 OptionSpec<Integer> optMeasureBatchSize = parser.accepts("bs", "Batch size: number of benchmark method calls per operation. " + 106 "(some benchmark modes can ignore this setting)") 107 .withRequiredArg().ofType(Integer.class).describedAs("int"); 108 109 OptionSpec<String> optMeasureTime = parser.accepts("r", "Time to spend at each measurement iteration.") 110 .withRequiredArg().ofType(String.class).describedAs("time"); 111 112 OptionSpec<Integer> optWarmupCount = parser.accepts("wi", "Number of warmup iterations to do.") 113 .withRequiredArg().ofType(Integer.class).describedAs("int"); 114 115 OptionSpec<Integer> optWarmupBatchSize = parser.accepts("wbs", "Warmup batch size: number of benchmark method calls per operation. " + 116 "(some benchmark modes can ignore this setting)") 117 .withRequiredArg().ofType(Integer.class).describedAs("int"); 118 119 OptionSpec<String> optWarmupTime = parser.accepts("w", "Time to spend at each warmup iteration.") 120 .withRequiredArg().ofType(String.class).describedAs("time"); 121 122 OptionSpec<String> optTimeoutTime = parser.accepts("to", "Timeout for benchmark iteration.") 123 .withRequiredArg().ofType(String.class).describedAs("time"); 124 125 OptionSpec<String> optThreads = parser.accepts("t", "Number of worker threads to run with.") 126 .withRequiredArg().ofType(String.class).describedAs("int"); 127 128 OptionSpec<String> optBenchmarkMode = parser.accepts("bm", "Benchmark mode. Available modes are: " + Mode.getKnown()) 129 .withRequiredArg().ofType(String.class).withValuesSeparatedBy(',').describedAs("mode"); 130 131 OptionSpec<Boolean> optSyncIters = parser.accepts("si", "Synchronize iterations?") 132 .withOptionalArg().ofType(Boolean.class).describedAs("bool"); 133 134 OptionSpec<Boolean> optGC = parser.accepts("gc", "Should JMH force GC between iterations?") 135 .withOptionalArg().ofType(Boolean.class).describedAs("bool"); 136 137 OptionSpec<Boolean> optFOE = parser.accepts("foe", "Should JMH fail immediately if any benchmark had" + 138 " experienced the unrecoverable error?") 139 .withOptionalArg().ofType(Boolean.class).describedAs("bool"); 140 141 OptionSpec<String> optVerboseMode = parser.accepts("v", "Verbosity mode. Available modes are: " + Arrays.toString(VerboseMode.values())) 142 .withRequiredArg().ofType(String.class).describedAs("mode"); 143 144 OptionSpec<String> optArgs = parser.nonOptions("Benchmarks to run (regexp+).") 145 .describedAs("regexp+"); 146 147 OptionSpec<Integer> optForks = parser.accepts("f", "How many times to forks a single benchmark." + 148 " Use 0 to disable forking altogether (WARNING: disabling forking may have detrimental" + 149 " impact on benchmark and infrastructure reliability, you might want to use different" + 150 " warmup mode instead).") 151 .withOptionalArg().ofType(Integer.class).describedAs("int"); 152 153 OptionSpec<Integer> optWarmupForks = parser.accepts("wf", "How many warmup forks to make " + 154 "for a single benchmark. 0 to disable warmup forks.") 155 .withRequiredArg().ofType(Integer.class).describedAs("int"); 156 157 OptionSpec<String> optOutput = parser.accepts("o", "Redirect human-readable output to file.") 158 .withRequiredArg().ofType(String.class).describedAs("filename"); 159 160 OptionSpec<String> optOutputResults = parser.accepts("rff", "Write results to given file.") 161 .withRequiredArg().ofType(String.class).describedAs("filename"); 162 163 OptionSpec<String> optProfilers = parser.accepts("prof", "Use profilers to collect additional data." + 164 " See the list of available profilers first.") 165 .withRequiredArg().withValuesSeparatedBy(',').ofType(String.class).describedAs("profiler+"); 166 167 OptionSpec<Integer> optThreadGroups = parser.accepts("tg", "Override thread group distribution for asymmetric benchmarks.") 168 .withRequiredArg().withValuesSeparatedBy(',').ofType(Integer.class).describedAs("int+"); 169 170 OptionSpec<String> optJvm = parser.accepts("jvm", "Custom JVM to use when forking (path to JVM executable).") 171 .withRequiredArg().ofType(String.class).describedAs("string"); 172 173 OptionSpec<String> optJvmArgs = parser.accepts("jvmArgs", "Custom JVM args to use when forking.") 174 .withRequiredArg().ofType(String.class).describedAs("string"); 175 176 OptionSpec<String> optJvmArgsAppend = parser.accepts("jvmArgsAppend", "Custom JVM args to use when forking (append these)") 177 .withRequiredArg().ofType(String.class).describedAs("string"); 178 179 OptionSpec<String> optJvmArgsPrepend = parser.accepts("jvmArgsPrepend", "Custom JVM args to use when forking (prepend these)") 180 .withRequiredArg().ofType(String.class).describedAs("string"); 181 182 OptionSpec<String> optTU = parser.accepts("tu", "Output time unit. Available time units are: [m, s, ms, us, ns].") 183 .withRequiredArg().ofType(String.class).describedAs("TU"); 184 185 OptionSpec<Integer> optOPI = parser.accepts("opi", "Operations per invocation.") 186 .withRequiredArg().ofType(Integer.class).describedAs("int"); 187 188 OptionSpec<String> optResultFormat = parser.accepts("rf", "Result format type. See the list of available result formats first.") 189 .withRequiredArg().ofType(String.class).describedAs("type"); 190 191 OptionSpec<String> optWarmupMode = parser.accepts("wm", "Warmup mode for warming up selected benchmarks. Warmup modes are: " + Arrays.toString(WarmupMode.values()) + ".") 192 .withRequiredArg().ofType(String.class).describedAs("mode"); 193 194 OptionSpec<String> optExcludes = parser.accepts("e", "Benchmarks to exclude from the run.") 195 .withRequiredArg().withValuesSeparatedBy(',').ofType(String.class).describedAs("regexp+"); 196 197 OptionSpec<String> optParams = parser.accepts("p", "Benchmark parameters. This option is expected to be used once" + 198 " per parameter. Parameter name and parameter values should be separated with equals sign." + 199 " Parameter values should be separated with commas.") 200 .withRequiredArg().ofType(String.class).describedAs("param={v,}*"); 201 202 OptionSpec<String> optWarmupBenchmarks = parser.accepts("wmb", "Warmup benchmarks to include in the run " + 203 "in addition to already selected. JMH will not measure these benchmarks, but only use them" + 204 " for the warmup.") 205 .withRequiredArg().withValuesSeparatedBy(',').ofType(String.class).describedAs("regexp+"); 206 207 parser.accepts("l", "List matching benchmarks and exit."); 208 parser.accepts("lrf", "List result formats."); 209 parser.accepts("lprof", "List profilers."); 210 parser.accepts("h", "Display help."); 211 212 try { 213 OptionSet set = parser.parse(argv); 214 215 if (set.has(optExcludes)) { 216 excludes.addAll(optExcludes.values(set)); 217 } 218 219 if (set.has(optWarmupBenchmarks)) { 220 warmupMicros.addAll(optWarmupBenchmarks.values(set)); 221 } 222 223 if (set.has(optTU)) { 224 String va = optTU.value(set); 225 TimeUnit tu; 226 if (va.equalsIgnoreCase("ns")) { 227 tu = TimeUnit.NANOSECONDS; 228 } else if (va.equalsIgnoreCase("us")) { 229 tu = TimeUnit.MICROSECONDS; 230 } else if (va.equalsIgnoreCase("ms")) { 231 tu = TimeUnit.MILLISECONDS; 232 } else if (va.equalsIgnoreCase("s")) { 233 tu = TimeUnit.SECONDS; 234 } else if (va.equalsIgnoreCase("m")) { 235 tu = TimeUnit.MINUTES; 236 } else if (va.equalsIgnoreCase("h")) { 237 tu = TimeUnit.HOURS; 238 } else { 239 throw new CommandLineOptionException("Unknown time unit: " + va); 240 } 241 timeUnit = Optional.of(tu); 242 } else { 243 timeUnit = Optional.none(); 244 } 245 246 opsPerInvocation = Optional.eitherOf(optOPI.value(set)); 247 248 if (set.has(optWarmupMode)) { 249 try { 250 warmupMode = Optional.of(WarmupMode.valueOf(optWarmupMode.value(set))); 251 } catch (IllegalArgumentException iae) { 252 throw new CommandLineOptionException(iae.getMessage(), iae); 253 } 254 } else { 255 warmupMode = Optional.none(); 256 } 257 258 if (set.has(optResultFormat)) { 259 try { 260 resultFormat = Optional.of(ResultFormatType.valueOf(optResultFormat.value(set).toUpperCase())); 261 } catch (IllegalArgumentException iae) { 262 throw new CommandLineOptionException(iae.getMessage(), iae); 263 } 264 } else { 265 resultFormat = Optional.none(); 266 } 267 268 help = set.has("h"); 269 list = set.has("l"); 270 listResultFormats = set.has("lrf"); 271 listProfilers = set.has("lprof"); 272 273 iterations = Optional.eitherOf(optMeasureCount.value(set)); 274 275 batchSize = Optional.eitherOf(optMeasureBatchSize.value(set)); 276 277 if (set.has(optMeasureTime)) { 278 String value = optMeasureTime.value(set); 279 try { 280 runTime = Optional.of(TimeValue.fromString(value)); 281 } catch (IllegalArgumentException iae) { 282 throw new CommandLineOptionException(iae.getMessage(), iae); 283 } 284 } else { 285 runTime = Optional.none(); 286 } 287 288 warmupIterations = Optional.eitherOf(optWarmupCount.value(set)); 289 290 warmupBatchSize = Optional.eitherOf(optWarmupBatchSize.value(set)); 291 292 if (set.has(optWarmupTime)) { 293 String value = optWarmupTime.value(set); 294 try { 295 warmupTime = Optional.of(TimeValue.fromString(value)); 296 } catch (IllegalArgumentException iae) { 297 throw new CommandLineOptionException(iae.getMessage(), iae); 298 } 299 } else { 300 warmupTime = Optional.none(); 301 } 302 303 if (set.has(optTimeoutTime)) { 304 String value = optTimeoutTime.value(set); 305 try { 306 timeout = Optional.of(TimeValue.fromString(value)); 307 } catch (IllegalArgumentException iae) { 308 throw new CommandLineOptionException(iae.getMessage(), iae); 309 } 310 } else { 311 timeout = Optional.none(); 312 } 313 314 if (set.has(optThreads)) { 315 String v = optThreads.value(set); 316 if (v.equalsIgnoreCase("max")) { 317 threads = Optional.of(Threads.MAX); 318 } else { 319 try { 320 threads = Optional.of(Integer.valueOf(v)); 321 } catch (IllegalArgumentException iae) { 322 throw new CommandLineOptionException(iae.getMessage(), iae); 323 } 324 } 325 } else { 326 threads = Optional.none(); 327 } 328 329 if (set.has(optBenchmarkMode)) { 330 try { 331 List<Mode> modes = new ArrayList<Mode>(); 332 for (String m : optBenchmarkMode.values(set)) { 333 modes.add(Mode.deepValueOf(m)); 334 } 335 benchMode.addAll(modes); 336 } catch (IllegalArgumentException iae) { 337 throw new CommandLineOptionException(iae.getMessage(), iae); 338 } 339 } 340 341 if (set.has(optSyncIters)) { 342 if (set.hasArgument(optSyncIters)) { 343 synchIterations = Optional.of(optSyncIters.value(set)); 344 } else { 345 synchIterations = Optional.of(true); 346 } 347 } else { 348 synchIterations = Optional.none(); 349 } 350 351 if (set.has(optGC)) { 352 if (set.hasArgument(optGC)) { 353 gcEachIteration = Optional.of(optGC.value(set)); 354 } else { 355 gcEachIteration = Optional.of(true); 356 } 357 } else { 358 gcEachIteration = Optional.none(); 359 } 360 361 if (set.has(optFOE)) { 362 if (set.hasArgument(optFOE)) { 363 failOnError = Optional.of(optFOE.value(set)); 364 } else { 365 failOnError = Optional.of(true); 366 } 367 } else { 368 failOnError = Optional.none(); 369 } 370 371 if (set.has(optVerboseMode)) { 372 try { 373 if (set.hasArgument(optVerboseMode)) { 374 verbose = Optional.of(VerboseMode.valueOf(set.valueOf(optVerboseMode).toUpperCase())); 375 } else { 376 verbose = Optional.of(VerboseMode.EXTRA); 377 } 378 } catch (IllegalArgumentException iae) { 379 throw new CommandLineOptionException(iae.getMessage(), iae); 380 } 381 } else { 382 verbose = Optional.none(); 383 } 384 385 regexps.addAll(set.valuesOf(optArgs)); 386 387 if (set.has(optForks)) { 388 if (set.hasArgument(optForks)) { 389 fork = Optional.of(optForks.value(set)); 390 } else { 391 fork = Optional.of(1); 392 } 393 } else { 394 fork = Optional.none(); 395 } 396 397 warmupFork = Optional.eitherOf(optWarmupForks.value(set)); 398 output = Optional.eitherOf(optOutput.value(set)); 399 result = Optional.eitherOf(optOutputResults.value(set)); 400 401 if (set.has(optProfilers)) { 402 try { 403 for (String m : optProfilers.values(set)) { 404 Class<? extends Profiler> pClass = ProfilerFactory.getProfilerByName(m); 405 if (pClass == null) { 406 throw new CommandLineOptionException("Unable to find profiler: " + m); 407 } 408 profilers.add(pClass); 409 } 410 } catch (IllegalArgumentException iae) { 411 throw new CommandLineOptionException(iae.getMessage(), iae); 412 } 413 } 414 415 if (set.has(optThreadGroups)) { 416 threadGroups.addAll(set.valuesOf(optThreadGroups)); 417 } 418 419 jvm = Optional.eitherOf(optJvm.value(set)); 420 421 if (set.hasArgument(optJvmArgs)) { 422 jvmArgs = Optional.<Collection<String>>of(Arrays.asList(optJvmArgs.value(set).trim().split("[ ]+"))); 423 } else { 424 jvmArgs = Optional.none(); 425 } 426 427 if (set.hasArgument(optJvmArgsAppend)) { 428 jvmArgsAppend = Optional.<Collection<String>>of(Arrays.asList(optJvmArgsAppend.value(set).trim().split("[ ]+"))); 429 } else { 430 jvmArgsAppend = Optional.none(); 431 } 432 433 if (set.hasArgument(optJvmArgsPrepend)) { 434 jvmArgsPrepend = Optional.<Collection<String>>of(Arrays.asList(optJvmArgsPrepend.value(set).trim().split("[ ]+"))); 435 } else { 436 jvmArgsPrepend = Optional.none(); 437 } 438 439 if (set.hasArgument(optParams)) { 440 for (String p : optParams.values(set)) { 441 String[] keys = p.split("="); 442 if (keys.length != 2) { 443 throw new CommandLineOptionException("Unable to parse parameter string \"" + p + "\""); 444 } 445 params.putAll(keys[0], Arrays.asList(keys[1].split(","))); 446 } 447 } 448 449 } catch (OptionException e) { 450 throw new CommandLineOptionException(e.getMessage(), e); 451 } 452 } 453 454 public void showHelp() throws IOException { 455 parser.printHelpOn(System.err); 456 } 457 458 public void listProfilers() { 459 StringBuilder supported = new StringBuilder(); 460 StringBuilder unsupported = new StringBuilder(); 461 462 List<Class<? extends Profiler>> discoveredProfilers = ProfilerFactory.getDiscoveredProfilers(); 463 464 for (Class<? extends Profiler> s : ProfilerFactory.getAvailableProfilers()) { 465 List<String> initMessages = new ArrayList<String>(); 466 if (ProfilerFactory.checkSupport(s, initMessages)) { 467 supported.append(String.format("%20s: %s %s\n", 468 ProfilerFactory.getLabel(s), 469 ProfilerFactory.getDescription(s), 470 discoveredProfilers.contains(s) ? "(discovered)" : "")); 471 } else { 472 unsupported.append(String.format("%20s: %s %s\n", 473 ProfilerFactory.getLabel(s), 474 ProfilerFactory.getDescription(s), 475 discoveredProfilers.contains(s) ? "(discovered)" : "")); 476 for (String im : initMessages) { 477 unsupported.append(String.format("%20s %s\n", "", im)); 478 } 479 unsupported.append("\n"); 480 } 481 } 482 483 if (!supported.toString().isEmpty()) { 484 System.out.println("Supported profilers:\n" + supported.toString()); 485 } 486 487 if (!unsupported.toString().isEmpty()) { 488 System.out.println("Unsupported profilers:\n" + unsupported.toString()); 489 } 490 } 491 492 public void listResultFormats() { 493 StringBuilder sb = new StringBuilder(); 494 495 for (ResultFormatType f : ResultFormatType.values()) { 496 sb.append(f.toString().toLowerCase()); 497 sb.append(", "); 498 } 499 sb.setLength(sb.length() - 2); 500 501 System.out.println("Available formats: " + sb.toString()); 502 } 503 504 public boolean shouldList() { 505 return list; 506 } 507 508 public boolean shouldListResultFormats() { 509 return listResultFormats; 510 } 511 512 public boolean shouldHelp() { 513 return help; 514 } 515 516 public boolean shouldListProfilers() { 517 return listProfilers; 518 } 519 520 @Override 521 public Optional<WarmupMode> getWarmupMode() { 522 return warmupMode; 523 } 524 525 @Override 526 public List<String> getIncludes() { 527 return regexps; 528 } 529 530 @Override 531 public List<String> getExcludes() { 532 return excludes; 533 } 534 535 @Override 536 public List<String> getWarmupIncludes() { 537 return warmupMicros; 538 } 539 540 @Override 541 public Optional<String> getJvm() { 542 return jvm; 543 } 544 545 @Override 546 public Optional<Collection<String>> getJvmArgs() { 547 return jvmArgs; 548 } 549 550 @Override 551 public Optional<Collection<String>> getJvmArgsAppend() { 552 return jvmArgsAppend; 553 } 554 555 @Override 556 public Optional<Collection<String>> getJvmArgsPrepend() { 557 return jvmArgsPrepend; 558 } 559 560 @Override 561 public Optional<Collection<String>> getParameter(String name) { 562 Collection<String> list = params.get(name); 563 if (list == null || list.isEmpty()){ 564 return Optional.none(); 565 } else { 566 return Optional.of(list); 567 } 568 } 569 570 @Override 571 public Optional<Integer> getForkCount() { 572 return fork; 573 } 574 575 @Override 576 public Optional<Integer> getWarmupForkCount() { 577 return warmupFork; 578 } 579 580 @Override 581 public Optional<String> getOutput() { 582 return output; 583 } 584 585 @Override 586 public Optional<ResultFormatType> getResultFormat() { 587 return resultFormat; 588 } 589 590 @Override 591 public Optional<String> getResult() { 592 return result; 593 } 594 595 @Override 596 public Optional<Integer> getMeasurementIterations() { 597 return iterations; 598 } 599 600 @Override 601 public Optional<Integer> getMeasurementBatchSize() { 602 return batchSize; 603 } 604 605 @Override 606 public Optional<TimeValue> getMeasurementTime() { 607 return runTime; 608 } 609 610 @Override 611 public Optional<TimeValue> getWarmupTime() { 612 return warmupTime; 613 } 614 615 @Override 616 public Optional<Integer> getWarmupIterations() { 617 return warmupIterations; 618 } 619 620 @Override 621 public Optional<Integer> getWarmupBatchSize() { 622 return warmupBatchSize; 623 } 624 625 @Override 626 public Optional<Integer> getThreads() { 627 return threads; 628 } 629 630 @Override 631 public Optional<int[]> getThreadGroups() { 632 if (threadGroups.isEmpty()) { 633 return Optional.none(); 634 } else { 635 int[] r = new int[threadGroups.size()]; 636 for (int c = 0; c < r.length; c++) { 637 r[c] = threadGroups.get(c); 638 } 639 return Optional.of(r); 640 } 641 } 642 643 @Override 644 public Optional<Boolean> shouldDoGC() { 645 return gcEachIteration; 646 } 647 648 @Override 649 public Optional<Boolean> shouldSyncIterations() { 650 return synchIterations; 651 } 652 653 @Override 654 public Optional<VerboseMode> verbosity() { 655 return verbose; 656 } 657 658 @Override 659 public Optional<TimeUnit> getTimeUnit() { 660 return timeUnit; 661 } 662 663 @Override 664 public Optional<Integer> getOperationsPerInvocation() { 665 return opsPerInvocation; 666 } 667 668 @Override 669 public Optional<Boolean> shouldFailOnError() { 670 return failOnError; 671 } 672 673 @Override 674 public Set<Class<? extends Profiler>> getProfilers() { 675 return profilers; 676 } 677 678 @Override 679 public Collection<Mode> getBenchModes() { 680 return new HashSet<Mode>(benchMode); 681 } 682 683 @Override 684 public Optional<TimeValue> getTimeout() { 685 return timeout; 686 } 687 }