1 /* 2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package j2dbench.report; 33 34 import java.util.Vector; 35 import java.util.Hashtable; 36 import java.util.Enumeration; 37 import java.io.BufferedReader; 38 import java.io.FileReader; 39 import java.io.IOException; 40 import java.io.PrintStream; 41 42 public class J2DAnalyzer { 43 static Vector results = new Vector(); 44 static GroupResultSetHolder groupHolder; 45 46 static final int BEST = 1; /* The best score */ 47 static final int WORST = 2; /* The worst score */ 48 static final int AVERAGE = 3; /* Average of all scores */ 49 static final int MIDAVG = 4; /* Average of all but the best and worst */ 50 51 static int mode = MIDAVG; 52 53 public static void usage(PrintStream out) { 54 out.println("usage:"); 55 out.println(" java -jar J2DAnalyzer.jar [Option]*"); 56 out.println(); 57 out.println("where options are any of the following in any order:"); 58 out.println(" -Help|-Usage "+ 59 "print out this usage statement"); 60 out.println(" -Group:<groupname> "+ 61 "the following result sets are combined into a group"); 62 out.println(" -NoGroup "+ 63 "the following result sets stand on their own"); 64 out.println(" -ShowUncontested "+ 65 "show results even when only result set has a result"); 66 out.println(" -Graph "+ 67 "graph the results visually (using lines of *'s)"); 68 out.println(" -Best "+ 69 "use best time within a resultset"); 70 out.println(" -Worst "+ 71 "use worst time within a resultset"); 72 out.println(" -Average|-Avg "+ 73 "use average of all times within a resultset"); 74 out.println(" -MidAverage|-MidAvg "+ 75 "like -Average but ignore best and worst times"); 76 out.println(" <resultfilename> "+ 77 "load in results from named file"); 78 out.println(); 79 out.println("results within a result set "+ 80 "use Best/Worst/Average mode"); 81 out.println("results within a group "+ 82 "are best of all result sets in that group"); 83 } 84 85 public static void main(String argv[]) { 86 boolean gavehelp = false; 87 boolean graph = false; 88 boolean ignoreuncontested = true; 89 if (argv.length > 0 && argv[0].equalsIgnoreCase("-html")) { 90 String newargs[] = new String[argv.length-1]; 91 System.arraycopy(argv, 1, newargs, 0, newargs.length); 92 HTMLSeriesReporter.main(newargs); 93 return; 94 } 95 for (int i = 0; i < argv.length; i++) { 96 String arg = argv[i]; 97 if (arg.regionMatches(true, 0, "-Group:", 0, 7)) { 98 groupHolder = new GroupResultSetHolder(); 99 groupHolder.setTitle(arg.substring(7)); 100 results.add(groupHolder); 101 } else if (arg.equalsIgnoreCase("-NoGroup")) { 102 groupHolder = null; 103 } else if (arg.equalsIgnoreCase("-ShowUncontested")) { 104 ignoreuncontested = false; 105 } else if (arg.equalsIgnoreCase("-Graph")) { 106 graph = true; 107 } else if (arg.equalsIgnoreCase("-Best")) { 108 mode = BEST; 109 } else if (arg.equalsIgnoreCase("-Worst")) { 110 mode = WORST; 111 } else if (arg.equalsIgnoreCase("-Average") || 112 arg.equalsIgnoreCase("-Avg")) 113 { 114 mode = AVERAGE; 115 } else if (arg.equalsIgnoreCase("-MidAverage") || 116 arg.equalsIgnoreCase("-MidAvg")) 117 { 118 mode = MIDAVG; 119 } else if (arg.equalsIgnoreCase("-Help") || 120 arg.equalsIgnoreCase("-Usage")) 121 { 122 usage(System.out); 123 gavehelp = true; 124 } else { 125 readResults(argv[i]); 126 } 127 } 128 129 if (results.size() == 0) { 130 if (!gavehelp) { 131 System.err.println("No results loaded"); 132 usage(System.err); 133 } 134 return; 135 } 136 137 int numsets = results.size(); 138 double totalscore[] = new double[numsets]; 139 int numwins[] = new int[numsets]; 140 int numties[] = new int[numsets]; 141 int numloss[] = new int[numsets]; 142 int numtests[] = new int[numsets]; 143 double bestscore[] = new double[numsets]; 144 double worstscore[] = new double[numsets]; 145 double bestspread[] = new double[numsets]; 146 double worstspread[] = new double[numsets]; 147 for (int i = 0; i < numsets; i++) { 148 bestscore[i] = Double.NEGATIVE_INFINITY; 149 worstscore[i] = Double.POSITIVE_INFINITY; 150 bestspread[i] = Double.POSITIVE_INFINITY; 151 worstspread[i] = Double.NEGATIVE_INFINITY; 152 } 153 154 ResultSetHolder base = (ResultSetHolder) results.elementAt(0); 155 Enumeration enum_ = base.getKeyEnumeration(); 156 Vector keyvector = new Vector(); 157 while (enum_.hasMoreElements()) { 158 keyvector.add(enum_.nextElement()); 159 } 160 String keys[] = new String[keyvector.size()]; 161 keyvector.copyInto(keys); 162 sort(keys); 163 enum_ = ResultHolder.commonkeys.keys(); 164 System.out.println("Options common across all tests:"); 165 if (ResultHolder.commonname != null && 166 ResultHolder.commonname.length() != 0) 167 { 168 System.out.println(" testname="+ResultHolder.commonname); 169 } 170 while (enum_.hasMoreElements()) { 171 Object key = enum_.nextElement(); 172 System.out.println(" "+key+"="+ResultHolder.commonkeymap.get(key)); 173 } 174 System.out.println(); 175 for (int k = 0; k < keys.length; k++) { 176 String key = keys[k]; 177 ResultHolder rh = base.getResultByKey(key); 178 double score = rh.getScore(); 179 double maxscore = score; 180 int numcontesting = 0; 181 for (int i = 0; i < numsets; i++) { 182 ResultSetHolder rsh = 183 (ResultSetHolder) results.elementAt(i); 184 ResultHolder rh2 = rsh.getResultByKey(key); 185 if (rh2 != null) { 186 if (graph) { 187 maxscore = Math.max(maxscore, rh2.getBestScore()); 188 } 189 numcontesting++; 190 } 191 } 192 if (ignoreuncontested && numcontesting < 2) { 193 continue; 194 } 195 System.out.println(rh.getShortKey()+":"); 196 for (int i = 0; i < numsets; i++) { 197 ResultSetHolder rsh = (ResultSetHolder) results.elementAt(i); 198 System.out.print(rsh.getTitle()+": "); 199 ResultHolder rh2 = rsh.getResultByKey(key); 200 if (rh2 == null) { 201 System.out.println("not run"); 202 } else { 203 double score2 = rh2.getScore(); 204 double percent = calcPercent(score, score2); 205 numtests[i]++; 206 if (percent < 97.5) { 207 numloss[i]++; 208 } else if (percent > 102.5) { 209 numwins[i]++; 210 } else { 211 numties[i]++; 212 } 213 totalscore[i] += score2; 214 if (bestscore[i] < percent) { 215 bestscore[i] = percent; 216 } 217 if (worstscore[i] > percent) { 218 worstscore[i] = percent; 219 } 220 double spread = rh2.getSpread(); 221 if (bestspread[i] > spread) { 222 bestspread[i] = spread; 223 } 224 if (worstspread[i] < spread) { 225 worstspread[i] = spread; 226 } 227 System.out.print(format(score2)); 228 System.out.print(" (var="+spread+"%)"); 229 System.out.print(" ("+percent+"%)"); 230 System.out.println(); 231 if (graph) { 232 int maxlen = 60; 233 int avgpos = 234 (int) Math.round(maxlen * score / maxscore); 235 Vector scores = rh2.getAllScores(); 236 for (int j = 0; j < scores.size(); j++) { 237 double s = ((Double) scores.get(j)).doubleValue(); 238 int len = (int) Math.round(maxlen * s / maxscore); 239 int pos = 0; 240 while (pos < len) { 241 System.out.print(pos == avgpos ? '|' : '*'); 242 pos++; 243 } 244 while (pos <= avgpos) { 245 System.out.print(pos == avgpos ? '|' : ' '); 246 pos++; 247 } 248 System.out.println(); 249 } 250 } 251 } 252 } 253 } 254 System.out.println(); 255 System.out.println("Summary:"); 256 for (int i = 0; i < numsets; i++) { 257 ResultSetHolder rsh = (ResultSetHolder) results.elementAt(i); 258 System.out.println(" "+rsh.getTitle()+": "); 259 if (numtests[i] == 0) { 260 System.out.println(" No tests matched reference results"); 261 } else { 262 double overallscore = totalscore[i]/numtests[i]; 263 System.out.println(" Number of tests: "+numtests[i]); 264 System.out.println(" Overall average: "+overallscore); 265 System.out.println(" Best spread: "+bestspread[i]+ 266 "% variance"); 267 System.out.println(" Worst spread: "+worstspread[i]+ 268 "% variance"); 269 if (i == 0) { 270 System.out.println(" (Basis for results comparison)"); 271 } else { 272 System.out.println(" Comparison to basis:"); 273 System.out.println(" Best result: "+bestscore[i]+ 274 "% of basis"); 275 System.out.println(" Worst result: "+worstscore[i]+ 276 "% of basis"); 277 System.out.println(" Number of wins: "+numwins[i]); 278 System.out.println(" Number of ties: "+numties[i]); 279 System.out.println(" Number of losses: "+numloss[i]); 280 } 281 } 282 System.out.println(); 283 } 284 } 285 286 public static void readResults(String filename) { 287 BufferedReader in; 288 try { 289 in = new BufferedReader(new FileReader(filename)); 290 readResults(in); 291 } catch (IOException e) { 292 System.out.println(e); 293 return; 294 } 295 } 296 297 public static void addResultSet(ResultSetHolder rs) { 298 if (groupHolder == null) { 299 results.add(rs); 300 } else { 301 groupHolder.addResultSet(rs); 302 } 303 } 304 305 public static void readResults(BufferedReader in) 306 throws IOException 307 { 308 String xmlver = in.readLine(); 309 if (xmlver == null || !xmlver.startsWith("<?xml version=\"1.0\"")) { 310 return; 311 } 312 while (true) { 313 String rsline = in.readLine(); 314 if (rsline == null) { 315 break; 316 } 317 rsline = rsline.trim(); 318 if (rsline.startsWith("<result-set version=")) { 319 String title = getStringAttribute(rsline, "name"); 320 if (title == null) { 321 title = "No title"; 322 } 323 SingleResultSetHolder srs = new SingleResultSetHolder(); 324 srs.setTitle(title); 325 readResultSet(in, srs); 326 addResultSet(srs); 327 } 328 } 329 } 330 331 public static void readResultSet(BufferedReader in, 332 SingleResultSetHolder srs) 333 throws IOException 334 { 335 String line; 336 while ((line = in.readLine()) != null) { 337 line = line.trim(); 338 if (line.startsWith("<test-desc>")) { 339 int index = line.indexOf("<", 11); 340 if (index < 0) { 341 index = line.length(); 342 } 343 line = line.substring(11, index); 344 srs.setDescription(line); 345 } else if (line.startsWith("<sys-prop")) { 346 String key = getStringAttribute(line, "key"); 347 String val = getStringAttribute(line, "value"); 348 if (key != null && val != null) { 349 srs.setProperty(key, val); 350 } 351 } else if (line.startsWith("<test-date")) { 352 srs.setStartTime(getLongAttribute(line, "start")); 353 srs.setEndTime(getLongAttribute(line, "end")); 354 } else if (line.startsWith("<result")) { 355 int numreps = getIntAttribute(line, "num-reps"); 356 int numunits = getIntAttribute(line, "num-units"); 357 String name = getStringAttribute(line, "name"); 358 if (numreps > 0 && numunits >= 0 && name != null) { 359 ResultHolder rh = new ResultHolder(srs); 360 rh.setName(name); 361 rh.setReps(numreps); 362 rh.setUnits(numunits); 363 readResult(in, rh); 364 srs.addResult(rh); 365 } 366 } else if (line.equals("</result-set>")) { 367 break; 368 } else { 369 System.err.println("Unrecognized line in Result-Set: "+line); 370 } 371 } 372 } 373 374 public static void readResult(BufferedReader in, ResultHolder rh) 375 throws IOException 376 { 377 String line; 378 while ((line = in.readLine()) != null) { 379 line = line.trim(); 380 if (line.startsWith("<option")) { 381 String key = getStringAttribute(line, "key"); 382 String val = getStringAttribute(line, "value"); 383 if (key != null && val != null) { 384 rh.addOption(key, val); 385 } 386 } else if (line.startsWith("<time")) { 387 long ms = getLongAttribute(line, "value"); 388 if (ms >= 0) { 389 rh.addTime(ms); 390 } 391 } else if (line.equals("</result>")) { 392 break; 393 } else { 394 System.err.println("Unrecognized line in Result: "+line); 395 } 396 } 397 } 398 399 public static String getStringAttribute(String line, String attrname) { 400 int index = line.indexOf(attrname+"="); 401 if (index < 0) { 402 return null; 403 } 404 index += attrname.length()+1; 405 int endindex; 406 if (line.charAt(index) == '\"') { 407 index++; 408 endindex = line.indexOf('\"', index); 409 } else { 410 endindex = -1; 411 } 412 if (endindex < 0) { 413 endindex = line.indexOf(' ', index); 414 } 415 if (endindex < 0) { 416 endindex = line.indexOf('>', index); 417 } 418 if (endindex < 0) { 419 endindex = line.length(); 420 } 421 return line.substring(index, endindex); 422 } 423 424 public static long getLongAttribute(String line, String attrname) { 425 String val = getStringAttribute(line, attrname); 426 if (val == null) { 427 return -1; 428 } 429 try { 430 return Long.parseLong(val); 431 } catch (NumberFormatException e) { 432 return -1; 433 } 434 } 435 436 public static int getIntAttribute(String line, String attrname) { 437 String val = getStringAttribute(line, attrname); 438 if (val == null) { 439 return -1; 440 } 441 try { 442 return Integer.parseInt(val); 443 } catch (NumberFormatException e) { 444 return -1; 445 } 446 } 447 448 public abstract static class ResultSetHolder { 449 private String title; 450 451 public void setTitle(String title) { 452 this.title = title; 453 } 454 455 public String getTitle() { 456 return title; 457 } 458 459 public abstract Enumeration getKeyEnumeration(); 460 461 public abstract Enumeration getResultEnumeration(); 462 463 public abstract ResultHolder getResultByKey(String key); 464 } 465 466 public static class GroupResultSetHolder extends ResultSetHolder { 467 private Vector members = new Vector(); 468 private Hashtable allresultkeys = new Hashtable(); 469 470 public void addResultSet(ResultSetHolder rsh) { 471 members.add(rsh); 472 Enumeration enum_ = rsh.getResultEnumeration(); 473 while (enum_.hasMoreElements()) { 474 ResultHolder rh = (ResultHolder) enum_.nextElement(); 475 String key = rh.getKey(); 476 allresultkeys.put(key, key); 477 } 478 } 479 480 private ResultSetHolder getResultSet(int index) { 481 return (ResultSetHolder) members.elementAt(index); 482 } 483 484 public Enumeration getKeyEnumeration() { 485 return allresultkeys.keys(); 486 } 487 488 public Enumeration getResultEnumeration() { 489 return new Enumerator(); 490 } 491 492 public ResultHolder getResultByKey(String key) { 493 ResultHolder best = null; 494 double bestscore = 0.0; 495 for (int i = 0; i < members.size(); i++) { 496 ResultHolder cur = getResultSet(i).getResultByKey(key); 497 if (cur != null) { 498 double curscore = cur.getScore(); 499 if (best == null || curscore > bestscore) { 500 best = cur; 501 bestscore = curscore; 502 } 503 } 504 } 505 return best; 506 } 507 508 public class Enumerator implements Enumeration { 509 Enumeration raw = getKeyEnumeration(); 510 511 public boolean hasMoreElements() { 512 return raw.hasMoreElements(); 513 } 514 515 public Object nextElement() { 516 return getResultByKey((String) raw.nextElement()); 517 } 518 } 519 } 520 521 public static class SingleResultSetHolder extends ResultSetHolder { 522 private String desc; 523 private long start; 524 private long end; 525 private Hashtable props = new Hashtable(); 526 private Vector results = new Vector(); 527 private Hashtable resultsbykey = new Hashtable(); 528 529 public void setDescription(String desc) { 530 this.desc = desc; 531 } 532 533 public String getDescription() { 534 return desc; 535 } 536 537 public void setStartTime(long ms) { 538 start = ms; 539 } 540 541 public long getStartTime() { 542 return start; 543 } 544 545 public void setEndTime(long ms) { 546 end = ms; 547 } 548 549 public long getEndTime() { 550 return end; 551 } 552 553 public void setProperty(String key, String value) { 554 props.put(key, value); 555 } 556 557 public Hashtable getProperties() { 558 return this.props; 559 } 560 561 public void addResult(ResultHolder rh) { 562 results.add(rh); 563 resultsbykey.put(rh.getKey(), rh); 564 } 565 566 public Enumeration getKeyEnumeration() { 567 return new Enumerator(); 568 } 569 570 public Enumeration getResultEnumeration() { 571 return results.elements(); 572 } 573 574 public ResultHolder getResultByKey(String key) { 575 return (ResultHolder) resultsbykey.get(key); 576 } 577 578 public class Enumerator implements Enumeration { 579 Enumeration raw = getResultEnumeration(); 580 581 public boolean hasMoreElements() { 582 return raw.hasMoreElements(); 583 } 584 585 public Object nextElement() { 586 return ((ResultHolder) raw.nextElement()).getKey(); 587 } 588 } 589 } 590 591 public static class ResultHolder { 592 public static Hashtable commonkeymap = new Hashtable(); 593 public static Hashtable commonkeys = new Hashtable(); 594 public static String commonname; 595 596 ResultSetHolder rsh; 597 private String name; 598 private String key; 599 private String shortkey; 600 private int numreps; 601 private int numunits; 602 private int numruns; 603 private long total; 604 private long longest; 605 private long shortest; 606 private Hashtable options = new Hashtable(); 607 private Vector times = new Vector(); 608 609 public ResultHolder(ResultSetHolder rsh) { 610 this.rsh = rsh; 611 } 612 613 public void setName(String name) { 614 this.name = name; 615 if (commonname == null) { 616 commonname = name; 617 } else if (!commonname.equals(name)) { 618 commonname = ""; 619 } 620 } 621 622 public String getName() { 623 return name; 624 } 625 626 public String getKey() { 627 if (key == null) { 628 key = makeKey(false); 629 } 630 return key; 631 } 632 633 public String getShortKey() { 634 if (shortkey == null) { 635 shortkey = makeKey(true); 636 } 637 return shortkey; 638 } 639 640 private String makeKey(boolean prunecommon) { 641 String keys[] = new String[options.size()]; 642 Enumeration enum_ = options.keys(); 643 int i = 0; 644 while (enum_.hasMoreElements()) { 645 keys[i++] = (String) enum_.nextElement(); 646 } 647 sort(keys); 648 String key = (prunecommon && commonname.equals(name)) ? "" : name; 649 for (i = 0; i < keys.length; i++) { 650 if (!prunecommon || !commonkeys.containsKey(keys[i])) { 651 key = key+","+keys[i]+"="+options.get(keys[i]); 652 } 653 } 654 if (key.length() == 0) { 655 key = name; 656 } else if (key.startsWith(",")) { 657 key = key.substring(1); 658 } 659 return key; 660 } 661 662 public void setReps(int numreps) { 663 this.numreps = numreps; 664 } 665 666 public int getReps() { 667 return numreps; 668 } 669 670 public void setUnits(int numunits) { 671 this.numunits = numunits; 672 } 673 674 public int getUnits() { 675 return numunits; 676 } 677 678 public void addOption(String key, String value) { 679 if (this.key != null) { 680 throw new InternalError("option added after key was made!"); 681 } 682 options.put(key, value); 683 Object commonval = commonkeymap.get(key); 684 if (commonval == null) { 685 commonkeymap.put(key, value); 686 commonkeys.put(key, key); 687 } else if (!commonval.equals(value)) { 688 commonkeys.remove(key); 689 } 690 } 691 692 public Hashtable getOptions() { 693 return options; 694 } 695 696 public void addTime(long ms) { 697 times.add(new Long(ms)); 698 if (numruns == 0) { 699 longest = shortest = ms; 700 } else { 701 if (longest < ms) longest = ms; 702 if (shortest > ms) shortest = ms; 703 } 704 total += ms; 705 numruns++; 706 } 707 708 public double getSpread() { 709 return calcPercent(shortest, longest - shortest); 710 } 711 712 public double getScore() { 713 double score = numreps; 714 if (numunits > 0) { 715 score *= numunits; 716 } 717 long divisor; 718 if (mode == BEST) { 719 divisor = shortest; 720 } else if (mode == WORST) { 721 divisor = longest; 722 } else if (mode == AVERAGE || numruns < 3) { 723 score *= numruns; 724 divisor = total; 725 } else { 726 score *= (numruns-2); 727 divisor = (total - longest - shortest); 728 } 729 score /= divisor; 730 return score; 731 } 732 733 public double getBestScore() { 734 double score = numreps; 735 if (numunits > 0) { 736 score *= numunits; 737 } 738 return score / shortest; 739 } 740 741 public Vector getAllScores() { 742 Vector scores = new Vector(); 743 744 double score = numreps; 745 if (numunits > 0) { 746 score *= numunits; 747 } 748 if (mode == BEST) { 749 scores.add(new Double(score / shortest)); 750 } else if (mode == WORST) { 751 scores.add(new Double(score / longest)); 752 } else { 753 long elimshort, elimlong; 754 if (mode == AVERAGE || numruns < 3) { 755 elimshort = elimlong = -1; 756 } else { 757 elimshort = shortest; 758 elimlong = longest; 759 } 760 for (int i = 0; i < times.size(); i++) { 761 long time = ((Long) times.get(i)).longValue(); 762 if (time == elimshort) { 763 elimshort = -1; 764 continue; 765 } 766 if (time == elimlong) { 767 elimlong = -1; 768 continue; 769 } 770 scores.add(new Double(score / time)); 771 } 772 } 773 return scores; 774 } 775 } 776 777 public static double calcPercent(double base, double val) { 778 val /= base; 779 val *= 10000; 780 val = Math.rint(val); 781 return val / 100; 782 } 783 784 public static String format(double val) { 785 long lval = (long) val; 786 String ret = String.valueOf(lval); 787 int digits = ret.length(); 788 if (digits > 17) { 789 ret = String.valueOf(val); 790 } else { 791 val -= lval; 792 String fraction = String.valueOf(val); 793 fraction = fraction.substring(fraction.indexOf('.')); 794 ret += fraction; 795 int len = digits+5; 796 if (len < 10) len = 10; 797 len++; 798 if (ret.length() > len) { 799 ret = ret.substring(0, len); 800 } 801 } 802 return ret; 803 } 804 805 public static void sort(String strs[]) { 806 for (int i = 1; i < strs.length; i++) { 807 for (int j = i; j > 0; j--) { 808 if (strs[j].compareTo(strs[j-1]) >= 0) { 809 break; 810 } 811 String tmp = strs[j-1]; 812 strs[j-1] = strs[j]; 813 strs[j] = tmp; 814 } 815 } 816 } 817 818 public static void setMode(int mode) { 819 if(mode >= BEST && mode <= MIDAVG) { 820 J2DAnalyzer.mode = mode; 821 } 822 else { 823 J2DAnalyzer.mode = MIDAVG; 824 } 825 } 826 }