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