#!/usr/local/bin/perl
# * © 2016 and later: Unicode, Inc. and others.
# * License & terms of use: http://www.unicode.org/copyright.html#License
# *******************************************************************************
# * Copyright (C) 2002-2007 International Business Machines Corporation and *
# * others. All Rights Reserved. *
# *******************************************************************************
use strict;
# Assume we are running within the icu4j root directory
use lib 'src/com/ibm/icu/dev/test/perf';
use Dataset;
#---------------------------------------------------------------------
# Test class
my $TESTCLASS = 'com.ibm.icu.dev.test.perf.UCharacterPerf';
# Methods to be tested. Each pair represents a test method and
# a baseline method which is used for comparison.
my @METHODS = (['JDKDigit', 'Digit'],
['JDKGetNumericValue', 'GetNumericValue'],
['JDKGetType', 'GetType'],
['JDKIsDefined', 'IsDefined'],
['JDKIsDigit', 'IsDigit'],
['JDKIsIdentifierIgnorable', 'IsIdentifierIgnorable'],
['JDKIsISOControl', 'IsISOControl'],
['JDKIsLetter', 'IsLetter'],
['JDKIsLetterOrDigit', 'IsLetterOrDigit'],
['JDKIsLowerCase', 'IsLowerCase'],
['JDKIsSpaceChar', 'IsSpaceChar'],
['JDKIsTitleCase', 'IsTitleCase'],
['JDKIsUnicodeIdentifierPart', 'IsUnicodeIdentifierPart'],
['JDKIsUnicodeIdentifierStart', 'IsUnicodeIdentifierStart'],
['JDKIsUpperCase', 'IsUpperCase'],
['JDKIsWhiteSpace', 'IsWhiteSpace'],
);
# Patterns which define the set of characters used for testing.
my @PATTERNS = ('0 ffff');
my $CALIBRATE = 2; # duration in seconds for initial calibration
my $DURATION = 10; # duration in seconds for each pass
my $NUMPASSES = 4; # number of passes. If > 1 then the first pass
# is discarded as a JIT warm-up pass.
my $TABLEATTR = 'BORDER="1" CELLPADDING="4" CELLSPACING="0"';
my $PLUS_MINUS = "±";
if ($NUMPASSES < 3) {
die "Need at least 3 passes. One is discarded (JIT warmup) and need two to have 1 degree of freedom (t distribution).";
}
my $OUT; # see out()
main();
#---------------------------------------------------------------------
# ...
sub main {
my $date = localtime;
my $title = "ICU4J Performance Test $date";
my $html = $date;
$html =~ s/://g; # ':' illegal
$html =~ s/\s*\d+$//; # delete year
$html =~ s/^\w+\s*//; # delete dow
$html = "perf $html.html";
open(HTML,">$html") or die "Can't write to $html: $!";
print HTML < $testMethod vs. $baselineMethod Raw data:$title
\n";
print HTML "$TESTCLASS
\n";
my $raw = "";
for my $methodPair (@METHODS) {
my $testMethod = $methodPair->[0];
my $baselineMethod = $methodPair->[1];
print HTML "\n";
print HTML " \n";
print HTML "
\n";
print HTML " \n";
$OUT = '';
for my $pat (@PATTERNS) {
print HTML "Pattern $testMethod ";
print HTML "$baselineMethod Ratio \n";
}
print HTML "$pat \n";
out("");
# measure the test method
out("
");
# output ratio
my $r = $t->divide($b);
my $mean = $r->getMean() - 1;
my $color = $mean < 0 ? "RED" : "BLACK";
print HTML " ");
print HTML "");
print "\n$testMethod $pat\n";
my $t = measure2($testMethod, $pat, -$DURATION);
out(" ", formatSeconds(4, $t->getMean(), $t->getError);
print HTML "/event \n";
# measure baseline method
out(" ");
print HTML "");
print "\nBegin $baselineMethod $pat\n";
my $b = measure2($baselineMethod, $pat, -$DURATION);
out(" ", formatSeconds(4, $b->getMean(), $t->getError);
print HTML "/event \n";
out("", formatPercent(3, $mean, $r->getError);
print HTML "
Measuring $method using $pat, "); if ($iterCount > 0) { out("$iterCount iterations/pass, $NUMPASSES passes
\n"); } else { out(-$iterCount, " seconds/pass, $NUMPASSES passes\n"); } # is $iterCount actually -seconds/pass? if ($iterCount < 0) { # calibrate: estimate ms/iteration print "Calibrating..."; my @t = callJava($method, $pat, -$CALIBRATE, 1); print "done.\n"; my @data = split(/\s+/, $t[0]->[2]); $data[0] *= 1.0e+3; my $timePerIter = 1.0e-3 * $data[0] / $data[1]; # determine iterations/pass $iterCount = int(-$iterCount / $timePerIter + 0.5); out("Calibration pass ($CALIBRATE sec): ");
out("$data[0] ms, ");
out("$data[1] iterations = ");
out(formatSeconds(4, $timePerIter), "/iteration
\n");
}
# run passes
print "Measuring $iterCount iterations x $NUMPASSES passes...";
my @t = callJava($method, $pat, $iterCount, $NUMPASSES);
print "done.\n";
my @ms = ();
my @b; # scratch
for my $a (@t) {
# $a->[0]: method name, corresponds to $method
# $a->[1]: 'begin' data, == $iterCount
# $a->[2]: 'end' data, of the form
\n");
out("Events per iteration: $eventsPerIter
\n");
my @ms_str = @ms;
$ms_str[0] .= " (discarded)" if (@ms_str > 1);
out("Raw times (ms/pass): ", join(", ", @ms_str), "
\n");
($iterCount, $eventsPerIter, @ms);
}
#---------------------------------------------------------------------
# Invoke java to run $TESTCLASS, passing it the given parameters.
#
# @param the method to run
# @param the number of iterations, or if negative, the duration
# in seconds. If more than on pass is desired, pass in
# a string, e.g., "100 100 100".
# @param the pattern defining characters to test, values in hex digits without 0x
#
# @return an array of results. Each result is an array REF
# describing one pass. The array REF contains:
# ->[0]: The method name as reported
# ->[1]: The params on the '=