12e5b6d6dSopenharmony_ci#!/usr/local/bin/perl
22e5b6d6dSopenharmony_ci# * © 2016 and later: Unicode, Inc. and others.
32e5b6d6dSopenharmony_ci# * License & terms of use: http://www.unicode.org/copyright.html
42e5b6d6dSopenharmony_ci# *******************************************************************************
52e5b6d6dSopenharmony_ci# * Copyright (C) 2002-2012 International Business Machines Corporation and     *
62e5b6d6dSopenharmony_ci# * others. All Rights Reserved.                                                *
72e5b6d6dSopenharmony_ci# *******************************************************************************
82e5b6d6dSopenharmony_ci
92e5b6d6dSopenharmony_ciuse XML::LibXML;
102e5b6d6dSopenharmony_ci
112e5b6d6dSopenharmony_ci# Assume we are running within the icu4j root directory
122e5b6d6dSopenharmony_ciuse lib '.';
132e5b6d6dSopenharmony_ciuse Dataset;
142e5b6d6dSopenharmony_cimy $OS=$^O;
152e5b6d6dSopenharmony_ci
162e5b6d6dSopenharmony_cimy $CLASSPATH;
172e5b6d6dSopenharmony_ciif ($OS eq "linux" || $OS eq "darwin") {
182e5b6d6dSopenharmony_ci	$CLASSPATH="../icu4j.jar:../tools/misc/out/lib/icu4j-tools.jar:out/bin";
192e5b6d6dSopenharmony_ci} else {
202e5b6d6dSopenharmony_ci	$CLASSPATH="../icu4j.jar;../tools/misc/out/lib/icu4j-tools.jar;out/bin";
212e5b6d6dSopenharmony_ci}
222e5b6d6dSopenharmony_ci#---------------------------------------------------------------------
232e5b6d6dSopenharmony_ci
242e5b6d6dSopenharmony_ci# Methods to be tested.  Each pair represents a test method and
252e5b6d6dSopenharmony_ci# a baseline method which is used for comparison.
262e5b6d6dSopenharmony_cimy @METHODS  = (
272e5b6d6dSopenharmony_ci                 ['TestJDKConstruction',     'TestICUConstruction'],
282e5b6d6dSopenharmony_ci                 ['TestJDKParse',            'TestICUParse'],
292e5b6d6dSopenharmony_ci                 ['TestJDKFormat',           'TestICUFormat']
302e5b6d6dSopenharmony_ci               );
312e5b6d6dSopenharmony_ci# Patterns which define the set of characters used for testing.
322e5b6d6dSopenharmony_cimy @OPTIONS = (
332e5b6d6dSopenharmony_ci#                 locale    pattern              date string
342e5b6d6dSopenharmony_ci                [ "en_US",  "dddd MMM yyyy",     "15 Jan 2007"],
352e5b6d6dSopenharmony_ci                [ "sw_KE",  "dddd MMM yyyy",     "15 Jan 2007"],
362e5b6d6dSopenharmony_ci                [ "en_US",  "HH:mm",             "13:13"],
372e5b6d6dSopenharmony_ci                [ "en_US",  "HH:mm zzzz",        "13:13 Pacific Standard Time"],
382e5b6d6dSopenharmony_ci                [ "en_US",  "HH:mm z",           "13:13 PST"],
392e5b6d6dSopenharmony_ci                [ "en_US",  "HH:mm Z",           "13:13 -0800"],
402e5b6d6dSopenharmony_ci              );
412e5b6d6dSopenharmony_ci
422e5b6d6dSopenharmony_cimy $THREADS;        # number of threads (input from command-line args)
432e5b6d6dSopenharmony_cimy $CALIBRATE = 2;  # duration in seconds for initial calibration
442e5b6d6dSopenharmony_cimy $DURATION  = 10; # duration in seconds for each pass
452e5b6d6dSopenharmony_cimy $NUMPASSES = 4;  # number of passes.  If > 1 then the first pass
462e5b6d6dSopenharmony_ci                    # is discarded as a JIT warm-up pass.
472e5b6d6dSopenharmony_ci
482e5b6d6dSopenharmony_cimy $TABLEATTR = 'BORDER="1" CELLPADDING="4" CELLSPACING="0"';
492e5b6d6dSopenharmony_ci
502e5b6d6dSopenharmony_cimy $PLUS_MINUS = "±";
512e5b6d6dSopenharmony_ci
522e5b6d6dSopenharmony_ciif ($NUMPASSES < 3) {
532e5b6d6dSopenharmony_ci    die "Need at least 3 passes.  One is discarded (JIT warmup) and need two to have 1 degree of freedom (t distribution).";
542e5b6d6dSopenharmony_ci}
552e5b6d6dSopenharmony_ci
562e5b6d6dSopenharmony_ci
572e5b6d6dSopenharmony_ci# run all tests with the specified number of threads from command-line input
582e5b6d6dSopenharmony_ci# (if there is no arguments, use $THREADS = 1)
592e5b6d6dSopenharmony_ciforeach my $arg ($#ARGV >= 0 ? @ARGV : "1") {
602e5b6d6dSopenharmony_ci  $THREADS = $arg;
612e5b6d6dSopenharmony_ci  main();
622e5b6d6dSopenharmony_ci}
632e5b6d6dSopenharmony_ci
642e5b6d6dSopenharmony_ci
652e5b6d6dSopenharmony_ci#---------------------------------------------------------------------
662e5b6d6dSopenharmony_cisub main {
672e5b6d6dSopenharmony_ci
682e5b6d6dSopenharmony_ci#-----------DATE FORMAT PERFORMANCE TESTS-----------------------------
692e5b6d6dSopenharmony_ci    my $testclass = 'com.ibm.icu.dev.test.perf.DateFormatPerformanceTest';
702e5b6d6dSopenharmony_ci    #my $threads = ($THREADS > 1) ? "($THREADS threads)" : "";
712e5b6d6dSopenharmony_ci
722e5b6d6dSopenharmony_ci    my $doc = XML::LibXML::Document->new('1.0', 'utf-8');
732e5b6d6dSopenharmony_ci    my $root = $doc->createElement("perfTestResults");
742e5b6d6dSopenharmony_ci
752e5b6d6dSopenharmony_ci #   my $raw = "";
762e5b6d6dSopenharmony_ci    my @shortNames = ( "open" , "parse", "fmt");
772e5b6d6dSopenharmony_ci    my $index=0;
782e5b6d6dSopenharmony_ci
792e5b6d6dSopenharmony_ci    for my $methodPair (@METHODS) {
802e5b6d6dSopenharmony_ci
812e5b6d6dSopenharmony_ci        my $testMethod = $methodPair->[0];
822e5b6d6dSopenharmony_ci        my $baselineMethod = $methodPair->[1];
832e5b6d6dSopenharmony_ci	my $testname = $shortNames[$index];
842e5b6d6dSopenharmony_ci	$index++;
852e5b6d6dSopenharmony_ci
862e5b6d6dSopenharmony_ci        $OUT = '';
872e5b6d6dSopenharmony_ci	my $patternCounter=1;
882e5b6d6dSopenharmony_ci
892e5b6d6dSopenharmony_ci        for my $pat (@OPTIONS) {
902e5b6d6dSopenharmony_ci
912e5b6d6dSopenharmony_ci            # measure the test method
922e5b6d6dSopenharmony_ci            my $t = measure2($testclass, $testMethod, $pat, -$DURATION);
932e5b6d6dSopenharmony_ci	    my $testResult = $t->getMean();
942e5b6d6dSopenharmony_ci	    my $jdkElement = $doc->createElement("perfTestResult");
952e5b6d6dSopenharmony_ci	    my $testName = "DateFmt-$testname-pat$patternCounter-JDK";
962e5b6d6dSopenharmony_ci	    $jdkElement->setAttribute("test" => $testName);
972e5b6d6dSopenharmony_ci	    $jdkElement->setAttribute("iterations" => 1);
982e5b6d6dSopenharmony_ci	    $jdkElement->setAttribute("time" => $testResult);
992e5b6d6dSopenharmony_ci	    $root->appendChild($jdkElement);
1002e5b6d6dSopenharmony_ci
1012e5b6d6dSopenharmony_ci            # measure baseline method
1022e5b6d6dSopenharmony_ci            my $b = measure2($testclass, $baselineMethod, $pat, -$DURATION);
1032e5b6d6dSopenharmony_ci            my $baseResult = $b->getMean();
1042e5b6d6dSopenharmony_ci	    my $icuElement = $doc->createElement("perfTestResult");
1052e5b6d6dSopenharmony_ci	    my $testName = "DateFmt-$testname-pat$patternCounter";
1062e5b6d6dSopenharmony_ci	    $patternCounter++;
1072e5b6d6dSopenharmony_ci	    $icuElement->setAttribute("test"=> $testName);
1082e5b6d6dSopenharmony_ci 	    $icuElement->setAttribute("iterations" => 1);
1092e5b6d6dSopenharmony_ci	    $icuElement->setAttribute("time" => $baseResult);
1102e5b6d6dSopenharmony_ci	    $root->appendChild($icuElement);
1112e5b6d6dSopenharmony_ci
1122e5b6d6dSopenharmony_ci       }
1132e5b6d6dSopenharmony_ci    }
1142e5b6d6dSopenharmony_ci
1152e5b6d6dSopenharmony_ci#------------------DECIMAL FORMAT TESTS---------------------------------
1162e5b6d6dSopenharmony_ci
1172e5b6d6dSopenharmony_ci    my $testclass = 'com.ibm.icu.dev.test.perf.DecimalFormatPerformanceTest';
1182e5b6d6dSopenharmony_ci    my @OPTIONS = (
1192e5b6d6dSopenharmony_ci#		locale	    pattern	date string
1202e5b6d6dSopenharmony_ci		[ "en_US", "#,###.##", "1,234.56"],
1212e5b6d6dSopenharmony_ci		[ "de_DE", "#,###.##", "1.234,56"],
1222e5b6d6dSopenharmony_ci		);
1232e5b6d6dSopenharmony_ci    my $index=0;
1242e5b6d6dSopenharmony_ci    for my $methodPair (@METHODS) {
1252e5b6d6dSopenharmony_ci
1262e5b6d6dSopenharmony_ci        my $testMethod = $methodPair->[0];
1272e5b6d6dSopenharmony_ci        my $baselineMethod = $methodPair->[1];
1282e5b6d6dSopenharmony_ci	my $testname = $shortNames[$index];
1292e5b6d6dSopenharmony_ci	$index++;
1302e5b6d6dSopenharmony_ci
1312e5b6d6dSopenharmony_ci
1322e5b6d6dSopenharmony_ci        for my $pat (@OPTIONS) {
1332e5b6d6dSopenharmony_ci	       my $patternName = $pat->[0];
1342e5b6d6dSopenharmony_ci
1352e5b6d6dSopenharmony_ci            # measure the test method
1362e5b6d6dSopenharmony_ci            my $t = measure2($testclass, $testMethod, $pat, -$DURATION);
1372e5b6d6dSopenharmony_ci	    my $testResult = $t->getMean();
1382e5b6d6dSopenharmony_ci	    my $jdkElement = $doc->createElement("perfTestResult");
1392e5b6d6dSopenharmony_ci	    my $testName = "NumFmt-$testname-$patternName-JDK";
1402e5b6d6dSopenharmony_ci	    $jdkElement->setAttribute("test" => $testName);
1412e5b6d6dSopenharmony_ci	    $jdkElement->setAttribute("iterations"=>1);
1422e5b6d6dSopenharmony_ci	    $jdkElement->setAttribute("time" => $testResult);
1432e5b6d6dSopenharmony_ci	    $root->appendChild($jdkElement);
1442e5b6d6dSopenharmony_ci
1452e5b6d6dSopenharmony_ci            # measure baseline method
1462e5b6d6dSopenharmony_ci            my $b = measure2($testclass, $baselineMethod, $pat, -$DURATION);
1472e5b6d6dSopenharmony_ci            my $baseResult = $b->getMean();
1482e5b6d6dSopenharmony_ci	    my $icuElement = $doc->createElement("perfTestResult");
1492e5b6d6dSopenharmony_ci	    my $testName = "NumFmt-$testname-$patternName";
1502e5b6d6dSopenharmony_ci	    $icuElement->setAttribute("test"=> $testName);
1512e5b6d6dSopenharmony_ci	    $icuElement->setAttribute("iterations"=>1);
1522e5b6d6dSopenharmony_ci	    $icuElement->setAttribute("time" => $baseResult);
1532e5b6d6dSopenharmony_ci	    $root->appendChild($icuElement);
1542e5b6d6dSopenharmony_ci	}
1552e5b6d6dSopenharmony_ci    }
1562e5b6d6dSopenharmony_ci
1572e5b6d6dSopenharmony_ci#----------------COLLATION PERFORMANCE TESTS--------------------------_
1582e5b6d6dSopenharmony_ci
1592e5b6d6dSopenharmony_ci    %dataFiles = (
1602e5b6d6dSopenharmony_ci   	   "en_US",         "TestNames_Latin.txt",
1612e5b6d6dSopenharmony_ci	   "da_DK",         "TestNames_Latin.txt",
1622e5b6d6dSopenharmony_ci	   "de_DE",         "TestNames_Latin.txt",
1632e5b6d6dSopenharmony_ci	   "de__PHONEBOOK", "TestNames_Latin.txt",
1642e5b6d6dSopenharmony_ci	   "fr_FR",         "TestNames_Latin.txt",
1652e5b6d6dSopenharmony_ci	   "ja_JP",         "TestNames_Latin.txt TestNames_Japanese_h.txt TestNames_Japanese_k.txt TestNames_Asian.txt",
1662e5b6d6dSopenharmony_ci	   "zh_CN",         "TestNames_Latin.txt TestNames_Chinese.txt",
1672e5b6d6dSopenharmony_ci	   "zh_TW",         "TestNames_Latin.txt TestNames_Chinese.txt",
1682e5b6d6dSopenharmony_ci	   "zh__PINYIN",    "TestNames_Latin.txt TestNames_Chinese.txt",
1692e5b6d6dSopenharmony_ci	   "ru_RU", 	    "TestNames_Latin.txt TestNames_Russian.txt",
1702e5b6d6dSopenharmony_ci	   "th",            "TestNames_Latin.txt TestNames_Thai.txt",
1712e5b6d6dSopenharmony_ci	   "ko_KR",         "TestNames_Latin.txt TestNames_Korean.txt",
1722e5b6d6dSopenharmony_ci	   );
1732e5b6d6dSopenharmony_ci
1742e5b6d6dSopenharmony_ci    #  Outer loop runs through the locales to test
1752e5b6d6dSopenharmony_ci    #     (Edit this list directly to make changes)
1762e5b6d6dSopenharmony_ci    #
1772e5b6d6dSopenharmony_ci    foreach  $locale (
1782e5b6d6dSopenharmony_ci	   "en_US",
1792e5b6d6dSopenharmony_ci	   "da_DK",
1802e5b6d6dSopenharmony_ci	   "de_DE",
1812e5b6d6dSopenharmony_ci	   "de__PHONEBOOK",
1822e5b6d6dSopenharmony_ci	   "fr_FR",
1832e5b6d6dSopenharmony_ci	   "ja_JP",
1842e5b6d6dSopenharmony_ci           "zh_CN",
1852e5b6d6dSopenharmony_ci	   "zh_TW",
1862e5b6d6dSopenharmony_ci	   "zh__PINYIN",
1872e5b6d6dSopenharmony_ci           "ko_KR",
1882e5b6d6dSopenharmony_ci	   "ru_RU",
1892e5b6d6dSopenharmony_ci	   "th",
1902e5b6d6dSopenharmony_ci                   )
1912e5b6d6dSopenharmony_ci       {
1922e5b6d6dSopenharmony_ci
1932e5b6d6dSopenharmony_ci
1942e5b6d6dSopenharmony_ci       #
1952e5b6d6dSopenharmony_ci       # Inner loop runs over the set of data files specified for each locale.
1962e5b6d6dSopenharmony_ci       #    (Edit the %datafiles initialization, above, to make changes.
1972e5b6d6dSopenharmony_ci       #
1982e5b6d6dSopenharmony_ci        $ff = $dataFiles{$locale};
1992e5b6d6dSopenharmony_ci        @ff = split(/[\s]+/, $ff);
2002e5b6d6dSopenharmony_ci        $counter = 1;
2012e5b6d6dSopenharmony_ci        foreach  $data (@ff) {
2022e5b6d6dSopenharmony_ci          #
2032e5b6d6dSopenharmony_ci          # Run ICU Test for this (locale, data file) pair.
2042e5b6d6dSopenharmony_ci          #
2052e5b6d6dSopenharmony_ci           $iStrCol = `java -classpath $CLASSPATH com.ibm.icu.dev.test.perf.CollationPerformanceTest -terse -file data/collation/$data -locale $locale -loop 1000 -binsearch`;
2062e5b6d6dSopenharmony_ciprint "java -classpath $CLASSPATH com.ibm.icu.dev.test.perf.CollationPerformanceTest -terse -file data/collation/$data -locale $locale -loop 1000 -binsearch\n";
2072e5b6d6dSopenharmony_ci  $iStrCol =~s/[,\s]*//g;  # whack off the leading "  ," in the returned result.
2082e5b6d6dSopenharmony_ci          doKeyTimes("java -classpath $CLASSPATH com.ibm.icu.dev.test.perf.CollationPerformanceTest -terse -file data/collation/$data -locale $locale -loop 1000 -keygen",
2092e5b6d6dSopenharmony_ci                    my $iKeyGen, my $iKeyLen);
2102e5b6d6dSopenharmony_ci
2112e5b6d6dSopenharmony_ci          #
2122e5b6d6dSopenharmony_ci          # Run Windows test for this (locale, data file) pair.  Only do if
2132e5b6d6dSopenharmony_ci          #    we are not on Windows 98/ME and we hava a windows langID
2142e5b6d6dSopenharmony_ci          #    for the locale.
2152e5b6d6dSopenharmony_ci          #
2162e5b6d6dSopenharmony_ci           $wStrCol =  $wKeyGen =  $wKeyLen = 0;
2172e5b6d6dSopenharmony_ci          my $wStrCol = `java -classpath $CLASSPATH com.ibm.icu.dev.test.perf.CollationPerformanceTest -terse -file data/collation/$data -locale $locale -loop 1000 -binsearch -java`;
2182e5b6d6dSopenharmony_ci          $wStrCol =~s/[,\s]*//g;  # whack off the leading "  ," in the returned result.
2192e5b6d6dSopenharmony_ci          doKeyTimes("java -classpath $CLASSPATH com.ibm.icu.dev.test.perf.CollationPerformanceTest -terse -file data/collation/$data -locale $locale -loop 1000 -keygen -java",
2202e5b6d6dSopenharmony_ci                     $wKeyGen, $wKeyLen);
2212e5b6d6dSopenharmony_ci
2222e5b6d6dSopenharmony_ci           $collDiff =  $keyGenDiff =  $keyLenDiff = 0;
2232e5b6d6dSopenharmony_ci          if ($wKeyLen > 0) {
2242e5b6d6dSopenharmony_ci               $collDiff   = (($wStrCol - $iStrCol) / $iStrCol) * 100;
2252e5b6d6dSopenharmony_ci               $keyGenDiff = (($wKeyGen - $iKeyGen) / $iKeyGen) * 100;
2262e5b6d6dSopenharmony_ci               $keyLenDiff = (($wKeyLen - $iKeyLen) / $iKeyLen) * 100;
2272e5b6d6dSopenharmony_ci          }
2282e5b6d6dSopenharmony_ci
2292e5b6d6dSopenharmony_ci	my $ICU = $doc->createElement("perfTestResult");
2302e5b6d6dSopenharmony_ci	my $testname = "Coll-$locale-data$counter-StrCol";
2312e5b6d6dSopenharmony_ci	#write the results corresponding to this local,data pair
2322e5b6d6dSopenharmony_ci	$ICU->setAttribute("test"=> $testname);
2332e5b6d6dSopenharmony_ci	$ICU->setAttribute("iterations"=>1000);
2342e5b6d6dSopenharmony_ci	$ICU->setAttribute("time"=> $iStrCol);
2352e5b6d6dSopenharmony_ci	$root->appendChild($ICU);
2362e5b6d6dSopenharmony_ci
2372e5b6d6dSopenharmony_ci	my $Key = $doc->createElement("perfTestResult");
2382e5b6d6dSopenharmony_ci	my $testname = "Coll-$locale-data$counter-keyGen";
2392e5b6d6dSopenharmony_ci	$Key->setAttribute("test"=> $testname);
2402e5b6d6dSopenharmony_ci	$Key->setAttribute("iterations"=>1000);
2412e5b6d6dSopenharmony_ci	$Key->setAttribute("time"=>$iKeyGen);
2422e5b6d6dSopenharmony_ci	$root->appendChild($Key);
2432e5b6d6dSopenharmony_ci
2442e5b6d6dSopenharmony_ci	my $JDK = $doc->createElement("perfTestResult");
2452e5b6d6dSopenharmony_ci	my $testname = "Coll-$locale-data$counter-StrCol-JDK";
2462e5b6d6dSopenharmony_ci	$JDK->setAttribute("test"=>$testname);
2472e5b6d6dSopenharmony_ci	$JDK->setAttribute("iterations"=>1000);
2482e5b6d6dSopenharmony_ci	$JDK->setAttribute("time"=>$wStrCol);
2492e5b6d6dSopenharmony_ci	$root->appendChild($JDK);
2502e5b6d6dSopenharmony_ci
2512e5b6d6dSopenharmony_ci	my $Key = $doc->createElement("perfTestResult");
2522e5b6d6dSopenharmony_ci	my $testname = "Coll-$locale-data$counter-keyGen-JDK";
2532e5b6d6dSopenharmony_ci	$Key->setAttribute("test"=>$testname);
2542e5b6d6dSopenharmony_ci	$Key->setAttribute("iterations"=>1000);
2552e5b6d6dSopenharmony_ci	$Key->setAttribute("time"=>$wKeyGen);
2562e5b6d6dSopenharmony_ci	$root->appendChild($Key);
2572e5b6d6dSopenharmony_ci	$counter++;
2582e5b6d6dSopenharmony_ci     }
2592e5b6d6dSopenharmony_ci   }
2602e5b6d6dSopenharmony_ci
2612e5b6d6dSopenharmony_ci
2622e5b6d6dSopenharmony_ci
2632e5b6d6dSopenharmony_ci#----------WRITE RESULTS TO perf.xml-----------------------
2642e5b6d6dSopenharmony_ci    $doc->setDocumentElement($root);
2652e5b6d6dSopenharmony_ci    open my $out_fh, '>', "perf.xml";
2662e5b6d6dSopenharmony_ci    print {$out_fh} $doc->toString;
2672e5b6d6dSopenharmony_ci}
2682e5b6d6dSopenharmony_ci
2692e5b6d6dSopenharmony_ci
2702e5b6d6dSopenharmony_ci#---------------------------------------------------------------------
2712e5b6d6dSopenharmony_ci# Append text to the global variable $OUT
2722e5b6d6dSopenharmony_cisub out {
2732e5b6d6dSopenharmony_ci   $OUT .= join('', @_);
2742e5b6d6dSopenharmony_ci}
2752e5b6d6dSopenharmony_ci
2762e5b6d6dSopenharmony_ci
2772e5b6d6dSopenharmony_ci#---------------------------------------------------------------------
2782e5b6d6dSopenharmony_ci# Measure a given test method with a give test pattern using the
2792e5b6d6dSopenharmony_ci# global run parameters.
2802e5b6d6dSopenharmony_ci#
2812e5b6d6dSopenharmony_ci# @param the method to run
2822e5b6d6dSopenharmony_ci# @param the pattern defining characters to test
2832e5b6d6dSopenharmony_ci# @param if >0 then the number of iterations per pass.  If <0 then
2842e5b6d6dSopenharmony_ci#        (negative of) the number of seconds per pass.
2852e5b6d6dSopenharmony_ci#
2862e5b6d6dSopenharmony_ci# @return a Dataset object, scaled by iterations per pass and
2872e5b6d6dSopenharmony_ci#         events per iteration, to give time per event
2882e5b6d6dSopenharmony_ci#
2892e5b6d6dSopenharmony_cisub measure2 {
2902e5b6d6dSopenharmony_ci    my @data = measure1(@_);
2912e5b6d6dSopenharmony_ci    my $iterPerPass = shift(@data);
2922e5b6d6dSopenharmony_ci    my $eventPerIter = shift(@data);
2932e5b6d6dSopenharmony_ci
2942e5b6d6dSopenharmony_ci    shift(@data) if (@data > 1); # discard first run
2952e5b6d6dSopenharmony_ci
2962e5b6d6dSopenharmony_ci    my $ds = Dataset->new(@data);
2972e5b6d6dSopenharmony_ci    $ds->setScale(1.0e-3 / ($iterPerPass * $eventPerIter));
2982e5b6d6dSopenharmony_ci    $ds;
2992e5b6d6dSopenharmony_ci}
3002e5b6d6dSopenharmony_ci
3012e5b6d6dSopenharmony_ci#---------------------------------------------------------------------
3022e5b6d6dSopenharmony_ci# Measure a given test method with a give test pattern using the
3032e5b6d6dSopenharmony_ci# global run parameters.
3042e5b6d6dSopenharmony_ci#
3052e5b6d6dSopenharmony_ci# @param the method to run
3062e5b6d6dSopenharmony_ci# @param the pattern defining characters to test
3072e5b6d6dSopenharmony_ci# @param if >0 then the number of iterations per pass.  If <0 then
3082e5b6d6dSopenharmony_ci#        (negative of) the number of seconds per pass.
3092e5b6d6dSopenharmony_ci#
3102e5b6d6dSopenharmony_ci# @return array of:
3112e5b6d6dSopenharmony_ci#         [0] iterations per pass
3122e5b6d6dSopenharmony_ci#         [1] events per iteration
3132e5b6d6dSopenharmony_ci#         [2..] ms reported for each pass, in order
3142e5b6d6dSopenharmony_ci#
3152e5b6d6dSopenharmony_cisub measure1 {
3162e5b6d6dSopenharmony_ci    my $testclass = shift;
3172e5b6d6dSopenharmony_ci    my $method = shift;
3182e5b6d6dSopenharmony_ci    my $pat = shift;
3192e5b6d6dSopenharmony_ci    my $iterCount = shift; # actually might be -seconds/pass
3202e5b6d6dSopenharmony_ci
3212e5b6d6dSopenharmony_ci    # is $iterCount actually -seconds/pass?
3222e5b6d6dSopenharmony_ci    if ($iterCount < 0) {
3232e5b6d6dSopenharmony_ci
3242e5b6d6dSopenharmony_ci        # calibrate: estimate ms/iteration
3252e5b6d6dSopenharmony_ci        print "Calibrating...";
3262e5b6d6dSopenharmony_ci        my @t = callJava($testclass, $method, $pat, -$CALIBRATE, 1);
3272e5b6d6dSopenharmony_ci        print "done.\n";
3282e5b6d6dSopenharmony_ci
3292e5b6d6dSopenharmony_ci        my @data = split(/\s+/, $t[0]->[2]);
3302e5b6d6dSopenharmony_ci        $data[0] *= 1.0e+3;
3312e5b6d6dSopenharmony_ci
3322e5b6d6dSopenharmony_ci        my $timePerIter = 1.0e-3 * $data[0] / $data[1];
3332e5b6d6dSopenharmony_ci
3342e5b6d6dSopenharmony_ci        # determine iterations/pass
3352e5b6d6dSopenharmony_ci        $iterCount = int(-$iterCount / $timePerIter + 0.5);
3362e5b6d6dSopenharmony_ci   }
3372e5b6d6dSopenharmony_ci
3382e5b6d6dSopenharmony_ci    # run passes
3392e5b6d6dSopenharmony_ci    print "Measuring $iterCount iterations x $NUMPASSES passes...";
3402e5b6d6dSopenharmony_ci    my @t = callJava($testclass, $method, $pat, $iterCount, $NUMPASSES);
3412e5b6d6dSopenharmony_ci    print "done.\n";
3422e5b6d6dSopenharmony_ci    my @ms = ();
3432e5b6d6dSopenharmony_ci    my @b; # scratch
3442e5b6d6dSopenharmony_ci    for my $a (@t) {
3452e5b6d6dSopenharmony_ci        # $a->[0]: method name, corresponds to $method
3462e5b6d6dSopenharmony_ci        # $a->[1]: 'begin' data, == $iterCount
3472e5b6d6dSopenharmony_ci        # $a->[2]: 'end' data, of the form <ms> <loops> <eventsPerIter>
3482e5b6d6dSopenharmony_ci        # $a->[3...]: gc messages from JVM during pass
3492e5b6d6dSopenharmony_ci        @b = split(/\s+/, $a->[2]);
3502e5b6d6dSopenharmony_ci        push(@ms, $b[0] * 1.0e+3);
3512e5b6d6dSopenharmony_ci    }
3522e5b6d6dSopenharmony_ci    my $eventsPerIter = $b[2];
3532e5b6d6dSopenharmony_ci
3542e5b6d6dSopenharmony_ci    my @ms_str = @ms;
3552e5b6d6dSopenharmony_ci    $ms_str[0] .= " (discarded)" if (@ms_str > 1);
3562e5b6d6dSopenharmony_ci
3572e5b6d6dSopenharmony_ci    ($iterCount, $eventsPerIter, @ms);
3582e5b6d6dSopenharmony_ci}
3592e5b6d6dSopenharmony_ci
3602e5b6d6dSopenharmony_ci#---------------------------------------------------------------------
3612e5b6d6dSopenharmony_ci# Invoke java to run $TESTCLASS, passing it the given parameters.
3622e5b6d6dSopenharmony_ci#
3632e5b6d6dSopenharmony_ci# @param the method to run
3642e5b6d6dSopenharmony_ci# @param the number of iterations, or if negative, the duration
3652e5b6d6dSopenharmony_ci#        in seconds.  If more than on pass is desired, pass in
3662e5b6d6dSopenharmony_ci#        a string, e.g., "100 100 100".
3672e5b6d6dSopenharmony_ci# @param the pattern defining characters to test
3682e5b6d6dSopenharmony_ci#
3692e5b6d6dSopenharmony_ci# @return an array of results.  Each result is an array REF
3702e5b6d6dSopenharmony_ci#         describing one pass.  The array REF contains:
3712e5b6d6dSopenharmony_ci#         ->[0]: The method name as reported
3722e5b6d6dSopenharmony_ci#         ->[1]: The params on the '= <meth> begin ...' line
3732e5b6d6dSopenharmony_ci#         ->[2]: The params on the '= <meth> end ...' line
3742e5b6d6dSopenharmony_ci#         ->[3..]: GC messages from the JVM, if any
3752e5b6d6dSopenharmony_ci#
3762e5b6d6dSopenharmony_cisub callJava {
3772e5b6d6dSopenharmony_ci    my $testclass = shift;
3782e5b6d6dSopenharmony_ci    my $method = shift;
3792e5b6d6dSopenharmony_ci    my $pat = shift;
3802e5b6d6dSopenharmony_ci    my $n = shift;
3812e5b6d6dSopenharmony_ci    my $passes = shift;
3822e5b6d6dSopenharmony_ci
3832e5b6d6dSopenharmony_ci    my $n = ($n < 0) ? "-t ".(-$n) : "-i ".$n;
3842e5b6d6dSopenharmony_ci
3852e5b6d6dSopenharmony_ci    my $cmd = "java -classpath $CLASSPATH $testclass $method $n -p $passes -L @$pat[0] \"@$pat[1]\" \"@$pat[2]\" -r $THREADS";
3862e5b6d6dSopenharmony_ci    print "[$cmd]\n"; # for debugging
3872e5b6d6dSopenharmony_ci    open(PIPE, "$cmd|") or die "Can't run \"$cmd\"";
3882e5b6d6dSopenharmony_ci    my @out;
3892e5b6d6dSopenharmony_ci    while (<PIPE>) {
3902e5b6d6dSopenharmony_ci        push(@out, $_);
3912e5b6d6dSopenharmony_ci    }
3922e5b6d6dSopenharmony_ci    close(PIPE) or die "Java failed: \"$cmd\"";
3932e5b6d6dSopenharmony_ci
3942e5b6d6dSopenharmony_ci    @out = grep(!/^\#/, @out);  # filter out comments
3952e5b6d6dSopenharmony_ci
3962e5b6d6dSopenharmony_ci    #print "[", join("\n", @out), "]\n";
3972e5b6d6dSopenharmony_ci
3982e5b6d6dSopenharmony_ci    my @results;
3992e5b6d6dSopenharmony_ci    my $method = '';
4002e5b6d6dSopenharmony_ci    my $data = [];
4012e5b6d6dSopenharmony_ci    foreach (@out) {
4022e5b6d6dSopenharmony_ci        next unless (/\S/);
4032e5b6d6dSopenharmony_ci
4042e5b6d6dSopenharmony_ci        if (/^=\s*(\w+)\s*(\w+)\s*(.*)/) {
4052e5b6d6dSopenharmony_ci            my ($m, $state, $d) = ($1, $2, $3);
4062e5b6d6dSopenharmony_ci            #print "$_ => [[$m $state $data]]\n";
4072e5b6d6dSopenharmony_ci            if ($state eq 'begin') {
4082e5b6d6dSopenharmony_ci                die "$method was begun but not finished" if ($method);
4092e5b6d6dSopenharmony_ci                $method = $m;
4102e5b6d6dSopenharmony_ci                push(@$data, $d);
4112e5b6d6dSopenharmony_ci                push(@$data, ''); # placeholder for end data
4122e5b6d6dSopenharmony_ci            } elsif ($state eq 'end') {
4132e5b6d6dSopenharmony_ci                if ($m ne $method) {
4142e5b6d6dSopenharmony_ci                    die "$method end does not match: $_";
4152e5b6d6dSopenharmony_ci                }
4162e5b6d6dSopenharmony_ci                $data->[1] = $d; # insert end data at [1]
4172e5b6d6dSopenharmony_ci                #print "#$method:", join(";",@$data), "\n";
4182e5b6d6dSopenharmony_ci                unshift(@$data, $method); # add method to start
4192e5b6d6dSopenharmony_ci
4202e5b6d6dSopenharmony_ci                push(@results, $data);
4212e5b6d6dSopenharmony_ci                $method = '';
4222e5b6d6dSopenharmony_ci                $data = [];
4232e5b6d6dSopenharmony_ci            } else {
4242e5b6d6dSopenharmony_ci                die "Can't parse: $_";
4252e5b6d6dSopenharmony_ci           }
4262e5b6d6dSopenharmony_ci        }
4272e5b6d6dSopenharmony_ci       elsif (/^\[/) {
4282e5b6d6dSopenharmony_ci            if ($method) {
4292e5b6d6dSopenharmony_ci                push(@$data, $_);
4302e5b6d6dSopenharmony_ci            } else {
4312e5b6d6dSopenharmony_ci                # ignore extraneous GC notices
4322e5b6d6dSopenharmony_ci            }
4332e5b6d6dSopenharmony_ci        }
4342e5b6d6dSopenharmony_ci        else {
4352e5b6d6dSopenharmony_ci            die "Can't parse: $_";
4362e5b6d6dSopenharmony_ci        }
4372e5b6d6dSopenharmony_ci    }
4382e5b6d6dSopenharmony_ci
4392e5b6d6dSopenharmony_ci    die "$method was begun but not finished" if ($method);
4402e5b6d6dSopenharmony_ci
4412e5b6d6dSopenharmony_ci    @results;
4422e5b6d6dSopenharmony_ci}
4432e5b6d6dSopenharmony_ci
4442e5b6d6dSopenharmony_ci#-----------------------------------------------------------------------------------
4452e5b6d6dSopenharmony_ci#  doKeyGenTimes($Command_to_run, $time, $key_length)
4462e5b6d6dSopenharmony_ci#       Do a key-generation test and return the time and key length/char values.
4472e5b6d6dSopenharmony_ci#
4482e5b6d6dSopenharmony_cisub doKeyTimes($$$) {
4492e5b6d6dSopenharmony_ci   # print "$_[0]\n";
4502e5b6d6dSopenharmony_ci   local($x) = `$_[0]`;                  # execute the collperf command.
4512e5b6d6dSopenharmony_ci   ($_[1], $_[2]) = split(/\,/, $x);     # collperf returns "time, keylength" string.
4522e5b6d6dSopenharmony_ci}
4532e5b6d6dSopenharmony_ci
4542e5b6d6dSopenharmony_ci
4552e5b6d6dSopenharmony_ci#eof
456