Update Caliper to r71.
diff --git a/build.xml b/build.xml
index a1584b0..2d52200 100644
--- a/build.xml
+++ b/build.xml
@@ -1,104 +1,103 @@
<?xml version="1.0"?>
-<project name="caliper" default="compile">
-
- <property environment="env"/>
-
+<project name="caliper" default="install">
<!-- can be overridden at the command line with -Dversion=
or in IDEA, in the ant properties dialog -->
- <property name="version" value="snapshot"/>
+ <property name="version" value="0.0"/> <!-- subversion revision? -->
- <path id="compile.classpath">
- <pathelement location="lib/google-collect-1.0-rc4.jar"/>
+ <property name="frameworkclasses" value="build/classes/framework"/>
+ <property name="otherclasses" value="build/classes/other"/>
+ <property name="installroot" value="build/caliper-${version}"/>
+ <property name="javadocroot" value="${installroot}/docs/api"/>
+ <property name="collections" value="lib/google-collect-1.0-rc4.jar"/>
+
+ <path id="dependencies">
+ <pathelement location="${collections}"/>
</path>
- <target name="compile" description="Compile Java source.">
- <mkdir dir="build/classes"/>
- <javac srcdir="src"
- debug="on"
- destdir="build/classes"
- source="1.5"
- target="1.5">
- <classpath refid="compile.classpath"/>
- </javac>
- <copy toDir="build/classes">
- <fileset dir="src" excludes="**/*.java"/>
- </copy>
- </target>
+ <path id="testdependencies">
+ <path refid="dependencies"/>
+ <pathelement location="${frameworkclasses}"/>
+ <pathelement location="lib/junit.jar"/>
+ </path>
- <target name="test.compile"
- depends="compile"
- description="Compile test source.">
- <mkdir dir="build/test"/>
- <javac srcdir="test"
+ <target name="compile"
+ description="Compile all Java source code">
+ <mkdir dir="${frameworkclasses}"/>
+ <javac srcdir="src"
+ includes="com/**"
+ destdir="${frameworkclasses}"
debug="on"
- destdir="build/test"
+ source="1.5"
+ target="1.5"
+ classpathref="dependencies">
+ <compilerarg value="-Xlint"/>
+ <!--compilerarg value="-Werror"/-->
+ </javac>
+
+ <mkdir dir="${otherclasses}"/>
+ <javac srcdir="src"
+ excludes="com/**"
+ debug="on"
+ destdir="${otherclasses}"
source="1.5"
target="1.5">
+ <compilerarg value="-Xlint"/>
+ <!--compilerarg value="-Werror"/-->
<classpath>
- <pathelement location="build/classes"/>
- <pathelement location="lib/google-collect-1.0-rc4.jar"/>
- <pathelement location="lib/junit.jar"/>
+ <path refid="testdependencies"/>
</classpath>
</javac>
- <copy toDir="build/test">
- <fileset dir="test" excludes="**/*.java"/>
- </copy>
</target>
<target name="test"
- depends="test.compile"
- description="Execute JUnit tests.">
- <java fork="true"
- classname="junit.textui.TestRunner"
- failonerror="true"
- taskname="junit">
+ depends="compile"
+ description="Run unit tests">
+ <junit fork="true"
+ haltonfailure="true">
<classpath>
- <pathelement location="build/test"/>
- <pathelement location="build/classes"/>
- <pathelement location="lib/junit.jar"/>
- <pathelement location="lib/google-collect-1.0-rc4.jar"/>
+ <pathelement location="${otherclasses}"/>
+ <path refid="testdependencies"/>
</classpath>
- <arg value="com.google.caliper.AllTests" />
- </java>
+ <batchtest>
+ <fileset dir="src">
+ <include name="test/*Test.java"/>
+ </fileset>
+ </batchtest>
+
+ </junit>
</target>
- <target name="clean"
- description="Remove generated files.">
- <delete dir="build"/>
- </target>
+ <target name="buildjar"
+ depends="compile"
+ description="Build JAR archive of caliper framework">
+ <mkdir dir="${installroot}/lib"/>
- <target name="jar" depends="compile" description="Build jars.">
- <mkdir dir="build/dist"/>
- <mkdir dir="build/dist/caliper-${version}"/>
- <jar jarfile="build/dist/caliper-${version}/caliper-${version}.jar">
- <fileset dir="build/classes"/>
- </jar>
- </target>
+ <taskdef name="jarjar"
+ classname="com.tonicsystems.jarjar.JarJarTask"
+ classpath="lib/jarjar-1.0rc8.jar"/>
- <target name="jarsrc" description="Build jar of source.">
- <jar jarfile="build/dist/caliper-${version}/src-${version}.zip">
- <fileset dir="src"/>
- </jar>
- </target>
+ <jarjar jarfile="${installroot}/lib/caliper-${version}.jar">
+ <fileset dir="${frameworkclasses}"/>
+ <zipfileset src="${collections}"/>
+ <rule pattern="com.google.common.**" result="com.google.caliper.internal.guava.@1"/>
+ <keep pattern="com.google.caliper.**"/>
- <target name="dist" depends="jar, jarsrc, javadoc"
- description="Build entire distribution.">
- <copy toDir="build/dist/caliper-${version}" file="COPYING"/>
- <copy toDir="build/dist/caliper-${version}">
- <fileset dir="build" includes="javadoc/**/*"/>
- </copy>
-
- <zip destfile="build/caliper-${version}.zip"
- basedir="build/dist"/>
+ <!-- include some files for GWT's benefit -->
+ <zipfileset dir="src">
+ <include name="com/google/caliper/Run.java"/>
+ <include name="com/google/caliper/Scenario.java"/>
+ <include name="CaliperCore.gwt.xml" />
+ </zipfileset>
+ </jarjar>
</target>
<target name="javadoc"
- description="Generate Javadocs.">
- <delete dir="build/javadoc"/>
- <mkdir dir="build/javadoc"/>
+ description="Generate API documentation to ${javadocroot}">
+ <delete dir="${javadocroot}"/> <!-- TODO: figure out how to make this more incremental -->
+ <mkdir dir="${javadocroot}"/>
<javadoc packagenames="com.google.caliper"
- destdir="build/javadoc"
+ destdir="${javadocroot}"
use="true"
author="true"
protected="true"
@@ -106,9 +105,44 @@
<sourcepath>
<pathelement location="src"/>
</sourcepath>
- <classpath refid="compile.classpath"/>
+ <classpath refid="dependencies"/>
<link href="http://google-collections.googlecode.com/svn/trunk/javadoc/"/>
<link href="http://java.sun.com/javase/6/docs/api"/>
</javadoc>
</target>
+
+ <target name="install" depends="buildjar, javadoc"
+ description="Create a complete installation tree in ./build/caliper-*">
+ <mkdir dir="${installroot}"/>
+ <zip zipfile="${installroot}/src-${version}.zip">
+ <fileset dir="src"/>
+ </zip>
+
+ <copy toDir="${installroot}" file="COPYING"/>
+ <copy toDir="${installroot}" file="src/scripts/caliper">
+ <filterset>
+ <filter token="VERSION" value="${version}"/>
+ </filterset>
+ </copy>
+ <chmod perm="ugo=rx" file="${installroot}/caliper"/>
+ </target>
+
+ <target name="dist"
+ depends="install"
+ description="Create a zipped distribution for upload to Google Code">
+ <zip destfile="build/caliper-${version}.zip">
+ <zipfileset dir="build/caliper-${version}"
+ excludes="caliper"
+ prefix="caliper-${version}"/>
+ <zipfileset file="build/caliper-${version}/caliper"
+ prefix="caliper-${version}"
+ filemode="555"/>
+ </zip>
+ </target>
+
+ <target name="clean"
+ description="Remove all generated files.">
+ <delete dir="build"/>
+ </target>
+
</project>
diff --git a/caliper.iml b/caliper.iml
new file mode 100644
index 0000000..70039aa
--- /dev/null
+++ b/caliper.iml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/ideabuild/framework" />
+ <output-test url="file://$MODULE_DIR$/ideabuild/other" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src/com" isTestSource="false" packagePrefix="com" />
+ <sourceFolder url="file://$MODULE_DIR$/src/examples" isTestSource="true" packagePrefix="examples" />
+ <sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" packagePrefix="test" />
+ <sourceFolder url="file://$MODULE_DIR$/src/tutorial" isTestSource="true" packagePrefix="tutorial" />
+ <excludeFolder url="file://$MODULE_DIR$/build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/google-collect-1.0-rc4.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library" scope="TEST">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/junit.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ </component>
+</module>
+
diff --git a/caliper.ipr b/caliper.ipr
index f4e0208..80e7392 100644
--- a/caliper.ipr
+++ b/caliper.ipr
@@ -1,15 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project relativePaths="false" version="4">
+<project version="4">
<component name="AntConfiguration">
<defaultAnt bundledAnt="true" />
- </component>
- <component name="BuildJarProjectSettings">
- <option name="BUILD_JARS_ON_MAKE" value="false" />
+ <buildFile url="file://$PROJECT_DIR$/build.xml">
+ <additionalClassPath />
+ <antReference projectDefault="true" />
+ <customJdkName value="" />
+ <maximumHeapSize value="128" />
+ <maximumStackSize value="2" />
+ <properties />
+ </buildFile>
</component>
<component name="CodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
- <ADDITIONAL_INDENT_OPTIONS fileType="java">
+ <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
+ <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+ <option name="ALIGN_MULTILINE_FOR" value="false" />
+ <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
+ <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
+ <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
+ <option name="BLANK_LINES_BEFORE_PACKAGE" value="1" />
+ <option name="BLANK_LINES_AROUND_CLASS" value="0" />
+ <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
+ <option name="USE_FQ_CLASS_NAMES_IN_JAVADOC" value="false" />
+ <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
+ <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+ <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+ <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+ <value />
+ </option>
+ <option name="IMPORT_LAYOUT_TABLE">
+ <value>
+ <package name="" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="" withSubpackages="true" static="true" />
+ </value>
+ </option>
+ <option name="RIGHT_MARGIN" value="100" />
+ <option name="CALL_PARAMETERS_WRAP" value="1" />
+ <option name="METHOD_PARAMETERS_WRAP" value="1" />
+ <option name="EXTENDS_LIST_WRAP" value="1" />
+ <option name="THROWS_LIST_WRAP" value="1" />
+ <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+ <option name="THROWS_KEYWORD_WRAP" value="1" />
+ <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+ <option name="BINARY_OPERATION_WRAP" value="1" />
+ <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+ <option name="TERNARY_OPERATION_WRAP" value="1" />
+ <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
+ <option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
+ <option name="FOR_STATEMENT_WRAP" value="1" />
+ <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+ <option name="ASSIGNMENT_WRAP" value="1" />
+ <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
+ <option name="LABELED_STATEMENT_WRAP" value="1" />
+ <option name="WRAP_COMMENTS" value="true" />
+ <option name="ASSERT_STATEMENT_WRAP" value="1" />
+ <option name="IF_BRACE_FORCE" value="3" />
+ <option name="DOWHILE_BRACE_FORCE" value="3" />
+ <option name="WHILE_BRACE_FORCE" value="3" />
+ <option name="FOR_BRACE_FORCE" value="3" />
+ <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
+ <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
+ <option name="JD_P_AT_EMPTY_LINES" value="false" />
+ <option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
+ <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
+ <option name="JD_KEEP_EMPTY_RETURN" value="false" />
+ <option name="METHOD_ANNOTATION_WRAP" value="5" />
+ <option name="CLASS_ANNOTATION_WRAP" value="5" />
+ <option name="FIELD_ANNOTATION_WRAP" value="5" />
+ <option name="PARAMETER_ANNOTATION_WRAP" value="1" />
+ <option name="VARIABLE_ANNOTATION_WRAP" value="1" />
+ <option name="ENUM_CONSTANTS_WRAP" value="2" />
+ <ADDITIONAL_INDENT_OPTIONS fileType="">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
@@ -18,8 +82,8 @@
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
- <ADDITIONAL_INDENT_OPTIONS fileType="jsp">
- <option name="INDENT_SIZE" value="4" />
+ <ADDITIONAL_INDENT_OPTIONS fileType="groovy">
+ <option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
@@ -27,6 +91,15 @@
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
+ <ADDITIONAL_INDENT_OPTIONS fileType="java">
+ <option name="INDENT_SIZE" value="2" />
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
+ <option name="TAB_SIZE" value="2" />
+ <option name="USE_TAB_CHARACTER" value="false" />
+ <option name="SMART_TABS" value="false" />
+ <option name="LABEL_INDENT_SIZE" value="0" />
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+ </ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="xml">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
@@ -38,90 +111,590 @@
</ADDITIONAL_INDENT_OPTIONS>
</value>
</option>
- <option name="USE_PER_PROJECT_SETTINGS" value="false" />
+ <option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
- <option name="DEPLOY_AFTER_MAKE" value="0" />
<resourceExtensions>
<entry name=".+\.(properties|xml|html|dtd|tld)" />
<entry name=".+\.(gif|png|jpeg|jpg)" />
</resourceExtensions>
- <wildcardResourcePatterns>
- <entry name="?*.properties" />
- <entry name="?*.xml" />
- <entry name="?*.gif" />
- <entry name="?*.png" />
- <entry name="?*.jpeg" />
- <entry name="?*.jpg" />
- <entry name="?*.html" />
- <entry name="?*.dtd" />
- <entry name="?*.tld" />
- <entry name="?*.ftl" />
- </wildcardResourcePatterns>
+ <wildcardResourcePatterns />
+ <annotationProcessing enabled="false" useClasspath="true" />
</component>
- <component name="CopyrightManager" default="">
+ <component name="CopyrightManager" default="Apache 2.0/Google">
+ <copyright>
+ <option name="notice" value="Copyright (C) &#36;today.year Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License." />
+ <option name="keyword" value="Copyright" />
+ <option name="allowReplaceKeyword" value="Copyright" />
+ <option name="myName" value="Apache 2.0/Google" />
+ <option name="myLocal" value="true" />
+ </copyright>
<module2copyright />
</component>
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component>
- <component name="EclipseCompilerSettings">
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="true" />
- <option name="DEPRECATION" value="false" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- <option name="MAXIMUM_HEAP_SIZE" value="128" />
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" defaultCharsetForPropertiesFiles="UTF-8">
+ <file url="file://$PROJECT_DIR$" charset="UTF-8" />
+ <file url="PROJECT" charset="UTF-8" />
</component>
- <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+ <component name="EntryPointsManager">
+ <entry_points version="2.0" />
+ </component>
<component name="InspectionProjectProfileManager">
- <option name="PROJECT_PROFILE" value="Project Default" />
- <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
- <scopes />
<profiles>
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
- <inspection_tool class="CloneDeclaresCloneNotSupported" level="WARNING" enabled="false" />
- <inspection_tool class="JavaDoc" level="WARNING" enabled="false">
+ <inspection_tool class="AbstractMethodCallInConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AbstractMethodOverridesAbstractMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AccessToNonThreadSafeStaticFieldFromInstance" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="nonThreadSafeTypes" value="java.text.DateFormat,java.util.Calendar" />
+ </inspection_tool>
+ <inspection_tool class="AccessToStaticFieldLockedOnInstance" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AmbiguousMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AnonymousClassVariableHidesContainingMethodVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ArchaicSystemPropertyAccess" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ArithmeticOnVolatileField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AssertEqualsMayBeAssertSame" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AssertStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AssignmentToCatchBlockParameter" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AssignmentToCollectionFieldFromParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignorePrivateMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="AssignmentToDateFieldFromParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignorePrivateMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="AssignmentToForLoopParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_checkForeachParameters" value="false" />
+ </inspection_tool>
+ <inspection_tool class="AssignmentToMethodParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreTransformationOfOriginalParameter" value="false" />
+ </inspection_tool>
+ <inspection_tool class="AssignmentToStaticFieldFromInstanceMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AssignmentUsedAsCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AwaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="AwaitWithoutCorrespondingSignal" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="BadOddness" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="BeforeClassOrAfterClassIsPublicStaticVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="BeforeOrAfterIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="BigDecimalEquals" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="BooleanMethodIsAlwaysInverted" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="BusyWait" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CStyleArrayDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CachedNumberConstructorCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CallToNativeMethodWhileLocked" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CallToStringConcatCanBeReplacedByOperator" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CastConflictsWithInstanceof" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CastThatLosesPrecision" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreIntegerCharCasts" value="false" />
+ </inspection_tool>
+ <inspection_tool class="CastToIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ChainedEquality" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CheckEmptyScriptTag" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="CheckValidXmlInScriptTagBody" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="ClassEscapesItsScope" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassInTopLevelPackage" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassInitializer" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassNameDiffersFromFileName" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassNewInstance" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassWithMultipleLoggers" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="loggerClassName" value="java.util.logging.Logger" />
+ </inspection_tool>
+ <inspection_tool class="CloneCallsSuperClone" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="CloneDeclaresCloneNotSupported" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="CollectionAddedToSelf" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CollectionsFieldAccessReplaceableByMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ComparableImplementedButEqualsNotOverridden" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ComparatorNotSerializable" enabled="true" level="INFO" enabled_by_default="true" />
+ <inspection_tool class="CompareToUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ComparisonOfShortAndChar" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ComparisonToNaN" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConditionSignal" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConditionalExpressionWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConfusingElse" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConfusingFloatingPointLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConfusingOctalEscape" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConstantAssertCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConstantJUnitAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConstantMathCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConstantOnLHSOfComparison" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConstantStringIntern" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConstantValueVariableUse" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ControlFlowStatementWithoutBraces" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CovariantEquals" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="DefaultNotLastCaseInSwitch" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="DivideByZero" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="DoubleCheckedLocking" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreOnVolatileVariables" value="false" />
+ </inspection_tool>
+ <inspection_tool class="DoubleNegation" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="DuplicateBooleanBranch" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="DuplicateCondition" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreMethodCalls" value="false" />
+ </inspection_tool>
+ <inspection_tool class="DynamicRegexReplaceableByCompiledPattern" enabled="true" level="INFO" enabled_by_default="true" />
+ <inspection_tool class="EmptyInitializer" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="EmptySynchronizedStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="EnumerationCanBeIteration" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="EqualsAndHashcode" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="EqualsHashCodeCalledOnUrl" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="EqualsUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ExceptionFromCatchWhichDoesntWrap" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="ignoreGetMessage" value="true" />
+ </inspection_tool>
+ <inspection_tool class="ExtendsThread" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ExtendsUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ExternalizableWithSerializationMethods" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FallthruInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FieldAccessedSynchronizedAndUnsynchronized" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="countGettersAndSetters" value="false" />
+ </inspection_tool>
+ <inspection_tool class="FieldHidesSuperclassField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ </inspection_tool>
+ <inspection_tool class="FieldMayBeFinal" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FinalMethodInFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FinalStaticMethod" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="Finalize" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FinalizeNotProtected" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FloatingPointEquality" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ForLoopReplaceableByWhile" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreLoopsWithoutConditions" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ForLoopThatDoesntUseLoopVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="HardcodedLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="HashCodeUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="HtmlExtraClosingTag" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="HtmlUnknownAttribute" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="myValues">
+ <value>
+ <list size="0" />
+ </value>
+ </option>
+ <option name="myCustomValuesEnabled" value="true" />
+ </inspection_tool>
+ <inspection_tool class="HtmlUnknownTag" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="myValues">
+ <value>
+ <list size="4">
+ <item index="0" class="java.lang.String" itemvalue="nobr" />
+ <item index="1" class="java.lang.String" itemvalue="noembed" />
+ <item index="2" class="java.lang.String" itemvalue="comment" />
+ <item index="3" class="java.lang.String" itemvalue="noscript" />
+ </list>
+ </value>
+ </option>
+ <option name="myCustomValuesEnabled" value="true" />
+ </inspection_tool>
+ <inspection_tool class="IOResource" enabled="true" level="INFO" enabled_by_default="true" />
+ <inspection_tool class="IfMayBeConditional" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IfStatementWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ImplicitNumericConversion" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreWideningConversions" value="true" />
+ <option name="ignoreCharConversions" value="false" />
+ <option name="ignoreConstantConversions" value="false" />
+ </inspection_tool>
+ <inspection_tool class="InconsistentLanguageLevel" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IndexOfReplaceableByContains" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InnerClassVariableHidesOuterClassVariable" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ </inspection_tool>
+ <inspection_tool class="InstanceVariableUninitializedUse" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignorePrimitives" value="false" />
+ </inspection_tool>
+ <inspection_tool class="InstanceofCatchParameter" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InstanceofIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InstanceofThis" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InstantiationOfUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IntLiteralMayBeLongLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IntegerDivisionInFloatingPointContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IntegerMultiplicationImplicitCastToLong" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IteratorHasNextCallsIteratorNext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IteratorNextDoesNotThrowNoSuchElementException" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="JUnit4AnnotatedMethodInJUnit3TestCase" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="JUnitAbstractTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[A-Z][A-Za-z\d]*TestCase" />
+ <option name="m_minLength" value="12" />
+ <option name="m_maxLength" value="64" />
+ </inspection_tool>
+ <inspection_tool class="JUnitTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[A-Z][A-Za-z\d]*Test" />
+ <option name="m_minLength" value="8" />
+ <option name="m_maxLength" value="64" />
+ </inspection_tool>
+ <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
- <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="public" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
- <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="protected" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
- <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
- <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="protected" />
+ <option name="REQUIRED_TAGS" value="@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
- <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="protected" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
- <option name="IGNORE_DEPRECATED" value="false" />
- <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+ <option name="IGNORE_DEPRECATED" value="true" />
+ <option name="IGNORE_JAVADOC_PERIOD" value="false" />
+ <option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="myAdditionalJavadocTags" value="" />
</inspection_tool>
+ <inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="LengthOneStringInIndexOf" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ListIndexOfReplaceableByContains" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="LocalVariableHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ <option name="m_ignoreStaticMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="LoggerInitializedWithForeignClass" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="loggerClassName" value="org.apache.log4j.Logger" />
+ <option name="loggerFactoryMethodName" value="getLogger" />
+ </inspection_tool>
+ <inspection_tool class="LoggingConditionDisagreesWithLogStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="LongLiteralsEndingWithLowercaseL" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="LoopConditionNotUpdatedInsideLoop" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreIterators" value="false" />
+ </inspection_tool>
+ <inspection_tool class="LoopWithImplicitTerminationCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MapReplaceableByEnumMap" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MavenModelInspection" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="MethodMayBeSynchronized" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodNameSameAsClassName" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="MethodOverloadsParentMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodOverridesPackageLocalMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodOverridesPrivateMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodOverridesStaticMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodReturnAlwaysConstant" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MismatchedArrayReadWrite" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_requireAnnotationsFirst" value="true" />
+ </inspection_tool>
+ <inspection_tool class="MisspelledCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledHashcode" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledSetUp" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledTearDown" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledToString" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MultipleDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MultipleExceptionsDeclaredOnTestMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MultipleTopLevelClassesInFile" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MultipleTypedDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NakedNotify" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NativeMethods" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NegatedConditional" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreNegatedNullComparison" value="true" />
+ </inspection_tool>
+ <inspection_tool class="NestedConditionalExpression" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NestedSynchronizedStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonFinalFieldOfException" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonFinalStaticVariableUsedInClassInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonProtectedConstructorInAbstractClass" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreNonPublicClasses" value="false" />
+ </inspection_tool>
+ <inspection_tool class="NonSerializableFieldInSerializableClass" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="superClassString" value="java.awt.Component" />
+ </inspection_tool>
+ <inspection_tool class="NonSerializableObjectBoundToHttpSession" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonSerializableObjectPassedToObjectStream" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonSerializableWithSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonSerializableWithSerializationMethods" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonShortCircuitBoolean" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonStaticFinalLogger" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="loggerClassName" value="java.util.logging.Logger" />
+ </inspection_tool>
+ <inspection_tool class="NonSynchronizedMethodOverridesSynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonThreadSafeLazyInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NotifyCalledOnCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NotifyNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NotifyWithoutCorrespondingWait" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NullableProblems" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
+ <option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
+ <option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
+ <option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
+ <option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
+ <option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
+ <option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
+ </inspection_tool>
+ <inspection_tool class="ObjectEquality" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreEnums" value="true" />
+ <option name="m_ignoreClassObjects" value="true" />
+ <option name="m_ignorePrivateConstructors" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ObjectNotify" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ObjectToString" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ObsoleteCollection" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreLibraryArguments" value="false" />
+ </inspection_tool>
+ <inspection_tool class="OctalAndDecimalIntegersMixed" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="OnDemandImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="OverlyComplexArithmeticExpression" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_limit" value="6" />
+ </inspection_tool>
+ <inspection_tool class="OverlyStrongTypeCast" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreInMatchingInstanceof" value="false" />
+ </inspection_tool>
+ <inspection_tool class="OverridableMethodCallDuringObjectConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="OverriddenMethodCallDuringObjectConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ParameterHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ <option name="m_ignoreStaticMethodParametersHidingInstanceFields" value="true" />
+ <option name="m_ignoreForConstructors" value="true" />
+ <option name="m_ignoreForPropertySetters" value="true" />
+ <option name="m_ignoreForAbstractMethods" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ParameterizedParametersStaticCollection" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="PatternNotApplicable" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="PatternOverriddenByNonAnnotatedMethod" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="PatternValidation" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="CHECK_NON_CONSTANT_VALUES" value="true" />
+ </inspection_tool>
+ <inspection_tool class="PointlessIndexOfComparison" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ProtectedMemberInFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="PublicConstructorInNonPublicClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="PublicField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreEnums" value="false" />
+ </inspection_tool>
+ <inspection_tool class="PublicFieldAccessedInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="PublicStaticArrayField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RawUseOfParameterizedType" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreObjectConstruction" value="true" />
+ <option name="ignoreTypeCasts" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ReadObjectAndWriteObjectPrivate" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReadObjectInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReadResolveAndWriteReplaceProtected" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantFieldInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantImplements" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreSerializable" value="false" />
+ <option name="ignoreCloneable" value="false" />
+ </inspection_tool>
+ <inspection_tool class="RedundantImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantMethodOverride" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantStringFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantSuppression" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantThrowsDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReplaceAllDot" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReplaceAssignmentWithOperatorAssignment" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreLazyOperators" value="true" />
+ <option name="ignoreObscureOperators" value="false" />
+ </inspection_tool>
+ <inspection_tool class="RequiredAttributes" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="myAdditionalRequiredHtmlAttributes" value="" />
+ </inspection_tool>
+ <inspection_tool class="ResultOfObjectAllocationIgnored" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReturnOfDateField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReuseOfLocalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RuntimeExec" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SafeLock" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SamePackageImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SerialPersistentFieldsWithWrongSignature" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SerialVersionUIDNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SerializableHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="superClassString" value="java.awt.Component" />
+ </inspection_tool>
+ <inspection_tool class="SerializableInnerClassHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="superClassString" value="java.awt.Component" />
+ </inspection_tool>
+ <inspection_tool class="SerializableInnerClassWithNonSerializableOuterClass" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="superClassString" value="java.awt.Component" />
+ </inspection_tool>
+ <inspection_tool class="SerializableWithUnconstructableAncestor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SetReplaceableByEnumSet" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SetupCallsSuperSetup" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SetupIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SignalWithoutCorrespondingAwait" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="SimplifiableJUnitAssertion" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true">
+ <option name="FORBID_15_API" value="false" />
+ <option name="FORBID_16_API" value="true" />
+ </inspection_tool>
+ <inspection_tool class="SizeReplaceableByIsEmpty" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreNegations" value="false" />
+ </inspection_tool>
+ <inspection_tool class="SleepWhileHoldingLock" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
+ <option name="processCode" value="true" />
+ <option name="processLiterals" value="true" />
+ <option name="processComments" value="true" />
+ </inspection_tool>
+ <inspection_tool class="StaticCallOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticFieldReferenceOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticInheritance" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticNonFinalField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticSuite" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticVariableInitialization" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignorePrimitives" value="false" />
+ </inspection_tool>
+ <inspection_tool class="StaticVariableUninitializedUse" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignorePrimitives" value="false" />
+ </inspection_tool>
+ <inspection_tool class="StringBufferReplaceableByStringBuilder" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StringEqualsEmptyString" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SubtractionInCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SuspiciousIndentAfterControlStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SwitchStatementWithConfusingDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SynchronizeOnLock" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SynchronizeOnThis" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_includeNativeMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="SynchronizedOnLiteralObject" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SystemRunFinalizersOnExit" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TailRecursion" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TeardownCallsSuperTeardown" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TeardownIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TestCaseInProductCode" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TestCaseWithConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TestCaseWithNoTestMethods" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreSupers" value="false" />
+ </inspection_tool>
+ <inspection_tool class="TestMethodInProductCode" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TestMethodIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TestMethodWithoutAssertion" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TestOnlyProblems" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TextLabelInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThisEscapedInConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadDumpStack" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadLocalNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadPriority" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadRun" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadStartInConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadStopSuspendResume" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadWithDefaultRunMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadYield" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThrowCaughtLocally" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreRethrownExceptions" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ThrowablePrintStackTrace" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TooBroadScope" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_allowConstructorAsInitializer" value="false" />
+ <option name="m_onlyLookAtBlocks" value="false" />
+ </inspection_tool>
+ <inspection_tool class="TransientFieldInNonSerializableClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TypeParameterExtendsFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TypeParameterHidesVisibleType" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UNUSED_SYMBOL" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="LOCAL_VARIABLE" value="true" />
+ <option name="FIELD" value="true" />
+ <option name="METHOD" value="true" />
+ <option name="CLASS" value="true" />
+ <option name="PARAMETER" value="true" />
+ <option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
+ <option name="INJECTION_ANNOS">
+ <value>
+ <list size="1">
+ <item index="0" class="java.lang.String" itemvalue="com.google.caliper.Param" />
+ </list>
+ </value>
+ </option>
+ </inspection_tool>
+ <inspection_tool class="UnaryPlus" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnconditionalWait" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnconstructableTestCase" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessarilyQualifiedStaticUsage" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreStaticFieldAccesses" value="false" />
+ <option name="m_ignoreStaticMethodCalls" value="false" />
+ <option name="m_ignoreStaticAccessFromStaticContext" value="false" />
+ </inspection_tool>
+ <inspection_tool class="UnnecessaryAnnotationParentheses" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryBlockStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryCallToStringValueOf" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryConstantArrayCreationExpression" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryEnumModifier" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryFinalOnLocalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryFinalOnParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="onlyWarnOnAbstractMethods" value="false" />
+ </inspection_tool>
+ <inspection_tool class="UnnecessaryFullyQualifiedName" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreJavadoc" value="false" />
+ </inspection_tool>
+ <inspection_tool class="UnnecessaryInheritDoc" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryInterfaceModifier" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryJavaDocLink" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryParentheses" enabled="true" level="INFO" enabled_by_default="true">
+ <option name="ignoreClarifyingParentheses" value="true" />
+ <option name="ignoreParenthesesOnConditionals" value="true" />
+ </inspection_tool>
+ <inspection_tool class="UnnecessaryQualifierForThis" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessarySuperConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessarySuperQualifier" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryUnaryMinus" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnpredictableBigDecimalConstructorCall" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreReferences" value="true" />
+ <option name="ignoreComplexLiterals" value="false" />
+ </inspection_tool>
+ <inspection_tool class="UnusedCatchParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreCatchBlocksWithComments" value="true" />
+ <option name="m_ignoreTestCases" value="true" />
+ </inspection_tool>
+ <inspection_tool class="UnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="ADD_MAINS_TO_ENTRIES" value="true" />
+ <option name="ADD_APPLET_TO_ENTRIES" value="true" />
+ <option name="ADD_SERVLET_TO_ENTRIES" value="true" />
+ <option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
+ <option name="ADDITIONAL_ANNOTATIONS">
+ <value>
+ <list size="1">
+ <item index="0" class="java.lang.String" itemvalue="javax.ws.rs.*" />
+ </list>
+ </value>
+ </option>
+ <option name="ADD_JUNIT_TO_ENTRIES" value="true" />
+ </inspection_tool>
+ <inspection_tool class="UnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnusedLibrary" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UseOfAnotherObjectsPrivateField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UseOfPropertiesAsHashtable" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UseOfSunClasses" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UtilityClassWithoutPrivateConstructor" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreClassesWithOnlyMain" value="false" />
+ </inspection_tool>
+ <inspection_tool class="VariableNotUsedInsideIf" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="VolatileArrayField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="VolatileLongOrDoubleField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitCalledOnCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitOrAwaitWithoutTimeout" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitWhileHoldingTwoLocks" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitWithoutCorrespondingNotify" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
+ <option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
+ <option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
+ </inspection_tool>
+ <inspection_tool class="WhileLoopSpinsOnField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreNonEmtpyLoops" value="false" />
+ </inspection_tool>
</profile>
</profiles>
- <list size="0" />
- </component>
- <component name="JavacSettings">
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="false" />
- <option name="DEPRECATION" value="true" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- <option name="MAXIMUM_HEAP_SIZE" value="128" />
+ <option name="PROJECT_PROFILE" value="Project Default" />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
</component>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
@@ -140,14 +713,6 @@
<option name="LOCALE" />
<option name="OPEN_IN_BROWSER" value="true" />
</component>
- <component name="JikesSettings">
- <option name="JIKES_PATH" value="" />
- <option name="DEBUGGING_INFO" value="true" />
- <option name="DEPRECATION" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="false" />
- <option name="IS_EMACS_ERRORS_MODE" value="true" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- </component>
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
@@ -272,31 +837,17 @@
<component name="ProjectDetails">
<option name="projectName" value="caliper" />
</component>
- <component name="ProjectFileVersion" converted="true" />
- <component name="ProjectKey">
- <option name="state" value="https://caliper.googlecode.com/svn/trunk/caliper.ipr" />
+ <component name="ProjectDictionaryState">
+ <dictionary name="kevinb" />
</component>
<component name="ProjectModuleManager">
<modules>
- <module fileurl="file://$PROJECT_DIR$/core.iml" filepath="$PROJECT_DIR$/core.iml" />
+ <module fileurl="file://$PROJECT_DIR$/caliper.iml" filepath="$PROJECT_DIR$/caliper.iml" />
+ <module fileurl="file://$PROJECT_DIR$/ideaplugin/ideaplugin.iml" filepath="$PROJECT_DIR$/ideaplugin/ideaplugin.iml" />
</modules>
</component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/out" />
- </component>
- <component name="ResourceManagerContainer">
- <option name="myResourceBundles">
- <value>
- <list size="0" />
- </value>
- </option>
- </component>
- <component name="RmicSettings">
- <option name="IS_EANABLED" value="false" />
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="false" />
- <option name="GENERATE_IIOP_STUBS" value="false" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/ideabuild" />
</component>
<component name="SvnBranchConfigurationManager">
<option name="myConfigurationMap">
@@ -304,9 +855,35 @@
<entry key="$PROJECT_DIR$">
<value>
<SvnBranchConfiguration>
+ <option name="branchMap">
+ <map>
+ <entry key="https://caliper.googlecode.com/svn/branches">
+ <value>
+ <list />
+ </value>
+ </entry>
+ <entry key="https://caliper.googlecode.com/svn/cloud">
+ <value>
+ <list />
+ </value>
+ </entry>
+ <entry key="https://caliper.googlecode.com/svn/static">
+ <value>
+ <list />
+ </value>
+ </entry>
+ <entry key="https://caliper.googlecode.com/svn/tags">
+ <value>
+ <list />
+ </value>
+ </entry>
+ </map>
+ </option>
<option name="branchUrls">
<list>
<option value="https://caliper.googlecode.com/svn/branches" />
+ <option value="https://caliper.googlecode.com/svn/cloud" />
+ <option value="https://caliper.googlecode.com/svn/static" />
<option value="https://caliper.googlecode.com/svn/tags" />
</list>
</option>
@@ -316,27 +893,10 @@
</entry>
</map>
</option>
- <option name="myVersion" value="124" />
<option name="mySupportsUserInfoFilter" value="true" />
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="svn" />
</component>
- <component name="libraryTable">
- <library name="Google Collections">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/google-collect-1.0-rc4.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- <library name="JUnit">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/junit.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </component>
</project>
diff --git a/core.iml b/core.iml
deleted file mode 100644
index 09f6e96..0000000
--- a/core.iml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module relativePaths="false" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="Google Collections" level="project" />
- <orderEntry type="library" name="JUnit" level="project" />
- </component>
-</module>
-
diff --git a/lib/jarjar-1.0rc8.jar b/lib/jarjar-1.0rc8.jar
new file mode 100644
index 0000000..89390bf
--- /dev/null
+++ b/lib/jarjar-1.0rc8.jar
Binary files differ
diff --git a/src/CaliperCore.gwt.xml b/src/CaliperCore.gwt.xml
new file mode 100644
index 0000000..161ac57
--- /dev/null
+++ b/src/CaliperCore.gwt.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module>
+ <inherits name='com.google.gwt.user.User'/>
+ <source path="com/google/caliper">
+ <include name="**/Run.java"/>
+ <include name="**/Scenario.java"/>
+ </source>
+</module>
\ No newline at end of file
diff --git a/src/com/google/caliper/Arguments.java b/src/com/google/caliper/Arguments.java
new file mode 100644
index 0000000..e5ff0f7
--- /dev/null
+++ b/src/com/google/caliper/Arguments.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.caliper;
+
+import com.google.caliper.UserException.DisplayUsageException;
+import com.google.caliper.UserException.MalformedParameterException;
+import com.google.caliper.UserException.MultipleBenchmarkClassesException;
+import com.google.caliper.UserException.NoBenchmarkClassException;
+import com.google.caliper.UserException.UnrecognizedOptionException;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Parse command line arguments for the runner and in-process runner.
+ */
+public final class Arguments {
+ private String suiteClassName;
+
+ /** JVMs to run in the benchmark */
+ private final Set<String> userVms = new LinkedHashSet<String>();
+
+ /**
+ * Parameter values specified by the user on the command line. Parameters with
+ * no value in this multimap will get their values from the benchmark suite.
+ */
+ private final Multimap<String, String> userParameters = LinkedHashMultimap.create();
+
+ private long warmupMillis = 5000;
+ private long runMillis = 5000;
+
+ /** The URL to post benchmark results to. */
+ private String postHost = "http://microbenchmarks.appspot.com/run/";
+
+ public String getSuiteClassName() {
+ return suiteClassName;
+ }
+
+ public Set<String> getUserVms() {
+ return userVms;
+ }
+
+ public Multimap<String, String> getUserParameters() {
+ return userParameters;
+ }
+
+ public long getWarmupMillis() {
+ return warmupMillis;
+ }
+
+ public long getRunMillis() {
+ return runMillis;
+ }
+
+ public String getPostHost() {
+ return postHost;
+ }
+
+ public static Arguments parse(String[] argsArray) {
+ Arguments result = new Arguments();
+
+ Iterator<String> args = Iterators.forArray(argsArray);
+ while (args.hasNext()) {
+ String arg = args.next();
+
+ if ("--help".equals(arg)) {
+ throw new DisplayUsageException();
+ }
+
+ if ("--postHost".equals(arg)) {
+ result.postHost = args.next();
+
+ } else if (arg.startsWith("-D")) {
+ int equalsSign = arg.indexOf('=');
+ if (equalsSign == -1) {
+ throw new MalformedParameterException(arg);
+ }
+ String name = arg.substring(2, equalsSign);
+ String value = arg.substring(equalsSign + 1);
+ result.userParameters.put(name, value);
+
+ } else if ("--warmupMillis".equals(arg)) {
+ result.warmupMillis = Long.parseLong(args.next());
+
+ } else if ("--runMillis".equals(arg)) {
+ result.runMillis = Long.parseLong(args.next());
+
+ } else if ("--vm".equals(arg)) {
+ result.userVms.add(args.next());
+
+ } else if (arg.startsWith("-")) {
+ throw new UnrecognizedOptionException(arg);
+
+ } else {
+ if (result.suiteClassName != null) {
+ throw new MultipleBenchmarkClassesException(result.suiteClassName, arg);
+ }
+ result.suiteClassName = arg;
+ }
+ }
+
+ if (result.suiteClassName == null) {
+ throw new NoBenchmarkClassException();
+ }
+
+ return result;
+ }
+
+ public static void printUsage() {
+ Arguments defaults = new Arguments();
+
+ System.out.println();
+ System.out.println("Usage: Runner [OPTIONS...] <benchmark>");
+ System.out.println();
+ System.out.println(" <benchmark>: a benchmark class or suite");
+ System.out.println();
+ System.out.println("OPTIONS");
+ System.out.println();
+ System.out.println(" -D<param>=<value>: fix a benchmark parameter to a given value.");
+ System.out.println(" When multiple values for the same parameter are given (via");
+ System.out.println(" multiple --Dx=y args), all supplied values are used.");
+ System.out.println();
+ System.out.println(" --inProcess: run the benchmark in the same JVM rather than spawning");
+ System.out.println(" another with the same classpath. By default each benchmark is");
+ System.out.println(" run in a separate VM");
+ System.out.println();
+ System.out.println(" --postHost <host>: the URL to post benchmark results to, or \"none\"");
+ System.out.println(" to skip posting results to the web.");
+ System.out.println(" default value: " + defaults.postHost);
+ System.out.println();
+ System.out.println(" --warmupMillis <millis>: duration to warmup each benchmark");
+ System.out.println();
+ System.out.println(" --runMillis <millis>: duration to execute each benchmark");
+ System.out.println();
+ System.out.println(" --vm <vm>: executable to test benchmark on");
+
+ // adding new options? don't forget to update executeForked()
+ }
+}
diff --git a/src/com/google/caliper/Benchmark.java b/src/com/google/caliper/Benchmark.java
index 19426e6..b5d35f9 100644
--- a/src/com/google/caliper/Benchmark.java
+++ b/src/com/google/caliper/Benchmark.java
@@ -16,7 +16,6 @@
package com.google.caliper;
-import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
diff --git a/src/com/google/caliper/Caliper.java b/src/com/google/caliper/Caliper.java
index 315431f..6c9d625 100644
--- a/src/com/google/caliper/Caliper.java
+++ b/src/com/google/caliper/Caliper.java
@@ -26,7 +26,7 @@
private final long warmupNanos;
private final long runNanos;
- public Caliper(long warmupMillis, long runMillis) {
+ Caliper(long warmupMillis, long runMillis) {
checkArgument(warmupMillis > 50);
checkArgument(runMillis > 50);
@@ -37,15 +37,24 @@
public double warmUp(TimedRunnable timedRunnable) throws Exception {
long startNanos = System.nanoTime();
long endNanos = startNanos + warmupNanos;
- int trials = 0;
long currentNanos;
+ int netReps = 0;
+ int reps = 1;
+
+ /*
+ * Run progressively more reps at a time until we cross our warmup
+ * threshold. This way any just-in-time compiler will be comfortable running
+ * multiple iterations of our measurement method.
+ */
while ((currentNanos = System.nanoTime()) < endNanos) {
- timedRunnable.run(1);
- trials++;
+ timedRunnable.run(reps);
+ netReps += reps;
+ reps *= 2;
}
- double nanosPerExecution = (currentNanos - startNanos) / trials;
+
+ double nanosPerExecution = (currentNanos - startNanos) / (double) netReps;
if (nanosPerExecution > 1000000000 || nanosPerExecution < 2) {
- throw new ConfigurationException("Runtime out of range");
+ throw new ConfigurationException("Runtime " + nanosPerExecution + " out of range");
}
return nanosPerExecution;
}
@@ -54,15 +63,51 @@
* In the run proper, we predict how extrapolate based on warmup how many
* runs we're going to need, and run them all in a single batch.
*/
- public double run(TimedRunnable test, double estimatedNanosPerTrial) throws Exception {
+ public double run(TimedRunnable test, double estimatedNanosPerTrial)
+ throws Exception {
+ @SuppressWarnings("NumericCastThatLosesPrecision")
int trials = (int) (runNanos / estimatedNanosPerTrial);
if (trials == 0) {
trials = 1;
}
+
+ double nanosPerTrial = measure(test, trials);
+
+ // if the runtime was in the expected range, return it. We're good.
+ if (isPlausible(estimatedNanosPerTrial, nanosPerTrial)) {
+ return nanosPerTrial;
+ }
+
+ // The runtime was outside of the expected range. Perhaps the VM is inlining
+ // things too aggressively? We'll run more rounds to confirm that the
+ // runtime scales with the number of trials.
+ double nanosPerTrial2 = measure(test, trials * 4);
+ if (isPlausible(nanosPerTrial, nanosPerTrial2)) {
+ return nanosPerTrial;
+ }
+
+ throw new ConfigurationException("Measurement error: "
+ + "runtime isn't proportional to the number of repetitions!");
+ }
+
+ /**
+ * Returns true if the given measurement is consistent with the expected
+ * measurement.
+ */
+ private boolean isPlausible(double expected, double measurement) {
+ double ratio = measurement / expected;
+ return ratio > 0.5 && ratio < 2.0;
+ }
+
+ private double measure(TimedRunnable test, int trials) throws Exception {
+ prepareForTest();
long startNanos = System.nanoTime();
test.run(trials);
- long endNanos = System.nanoTime();
- estimatedNanosPerTrial = (endNanos - startNanos) / trials;
- return estimatedNanosPerTrial;
+ return (System.nanoTime() - startNanos) / (double) trials;
+ }
+
+ private void prepareForTest() {
+ System.gc();
+ System.gc();
}
}
\ No newline at end of file
diff --git a/src/com/google/caliper/ConfigurationException.java b/src/com/google/caliper/ConfigurationException.java
index 5ad7bde..c4a35ec 100644
--- a/src/com/google/caliper/ConfigurationException.java
+++ b/src/com/google/caliper/ConfigurationException.java
@@ -19,13 +19,15 @@
/**
* Thrown upon occurrence of a configuration error.
*/
-public final class ConfigurationException extends RuntimeException {
+final class ConfigurationException extends RuntimeException {
- public ConfigurationException(String s) {
+ ConfigurationException(String s) {
super(s);
}
- public ConfigurationException(Throwable cause) {
+ ConfigurationException(Throwable cause) {
super(cause);
}
+
+ private static final long serialVersionUID = 0;
}
diff --git a/src/com/google/caliper/ConsoleReport.java b/src/com/google/caliper/ConsoleReport.java
index b367ec4..e59ceb6 100644
--- a/src/com/google/caliper/ConsoleReport.java
+++ b/src/com/google/caliper/ConsoleReport.java
@@ -16,8 +16,11 @@
package com.google.caliper;
-import com.google.common.collect.*;
-
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Ordering;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -39,13 +42,11 @@
final class ConsoleReport {
private static final int bargraphWidth = 30;
- private static final String vmKey = "vm";
- private final List<Parameter> parameters;
- private final Result result;
- private final List<Run> runs;
+ private final List<Variable> variables;
+ private final Run run;
+ private final List<Scenario> scenarios;
- private final double minValue;
private final double maxValue;
private final double logMaxValue;
private final int decimalDigits;
@@ -53,53 +54,51 @@
private final String units;
private final int measurementColumnLength;
- public ConsoleReport(Result result) {
- this.result = result;
+ ConsoleReport(Run run) {
+ this.run = run;
- double minValue = Double.POSITIVE_INFINITY;
- double maxValue = 0;
+ double min = Double.POSITIVE_INFINITY;
+ double max = 0;
Multimap<String, String> nameToValues = LinkedHashMultimap.create();
- List<Parameter> parametersBuilder = new ArrayList<Parameter>();
- for (Map.Entry<Run, Double> entry : result.getMeasurements().entrySet()) {
- Run run = entry.getKey();
+ List<Variable> variablesBuilder = new ArrayList<Variable>();
+ for (Map.Entry<Scenario, Double> entry : run.getMeasurements().entrySet()) {
+ Scenario scenario = entry.getKey();
double d = entry.getValue();
- minValue = Math.min(minValue, d);
- maxValue = Math.max(maxValue, d);
+ min = Math.min(min, d);
+ max = Math.max(max, d);
- for (Map.Entry<String, String> parameter : run.getParameters().entrySet()) {
- String name = parameter.getKey();
- nameToValues.put(name, parameter.getValue());
+ for (Map.Entry<String, String> variable : scenario.getVariables().entrySet()) {
+ String name = variable.getKey();
+ nameToValues.put(name, variable.getValue());
}
-
- nameToValues.put(vmKey, run.getVm());
}
for (Map.Entry<String, Collection<String>> entry : nameToValues.asMap().entrySet()) {
- Parameter parameter = new Parameter(entry.getKey(), entry.getValue());
- parametersBuilder.add(parameter);
+ Variable variable = new Variable(entry.getKey(), entry.getValue());
+ variablesBuilder.add(variable);
}
/*
- * Figure out how much influence each parameter has on the measured value.
- * We sum the measurements taken with each value of each parameter. For
- * parameters that have influence on the measurement, the sums will differ
- * by value. If the parameter has little influence, the sums will be similar
+ * Figure out how much influence each variable has on the measured value.
+ * We sum the measurements taken with each value of each variable. For
+ * variable that have influence on the measurement, the sums will differ
+ * by value. If the variable has little influence, the sums will be similar
* to one another and close to the overall average. We take the standard
- * deviation across each parameters collection of sums. Higher standard
+ * deviation across each variable's collection of sums. Higher standard
* deviation implies higher influence on the measured result.
*/
double sumOfAllMeasurements = 0;
- for (double measurement : result.getMeasurements().values()) {
+ for (double measurement : run.getMeasurements().values()) {
sumOfAllMeasurements += measurement;
}
- for (Parameter parameter : parametersBuilder) {
- int numValues = parameter.values.size();
+ for (Variable variable : variablesBuilder) {
+ int numValues = variable.values.size();
double[] sumForValue = new double[numValues];
- for (Map.Entry<Run, Double> entry : result.getMeasurements().entrySet()) {
- Run run = entry.getKey();
- sumForValue[parameter.index(run)] += entry.getValue();
+ for (Map.Entry<Scenario, Double> entry : run.getMeasurements().entrySet()) {
+ Scenario scenario = entry.getKey();
+ sumForValue[variable.index(scenario)] += entry.getValue();
}
double mean = sumOfAllMeasurements / sumForValue.length;
double stdDeviationSquared = 0;
@@ -107,16 +106,15 @@
double distance = value - mean;
stdDeviationSquared += distance * distance;
}
- parameter.stdDeviation = Math.sqrt(stdDeviationSquared / numValues);
+ variable.stdDeviation = Math.sqrt(stdDeviationSquared / numValues);
}
- this.parameters = new StandardDeviationOrdering().reverse().sortedCopy(parametersBuilder);
- this.runs = new ByParametersOrdering().sortedCopy(result.getMeasurements().keySet());
- this.minValue = minValue;
- this.maxValue = maxValue;
- this.logMaxValue = Math.log(maxValue);
+ this.variables = new StandardDeviationOrdering().reverse().sortedCopy(variablesBuilder);
+ this.scenarios = new ByVariablesOrdering().sortedCopy(run.getMeasurements().keySet());
+ this.maxValue = max;
+ this.logMaxValue = Math.log(max);
- int numDigitsInMin = (int) Math.ceil(Math.log10(minValue));
+ int numDigitsInMin = ceil(Math.log10(min));
if (numDigitsInMin > 9) {
divideBy = 1000000000;
decimalDigits = Math.max(0, 9 + 3 - numDigitsInMin);
@@ -134,41 +132,37 @@
decimalDigits = 0;
units = "ns";
}
- measurementColumnLength = maxValue > 0
- ? (int) Math.ceil(Math.log10(maxValue / divideBy)) + decimalDigits + 1
+ measurementColumnLength = max > 0
+ ? ceil(Math.log10(max / divideBy)) + decimalDigits + 1
: 1;
}
/**
- * A parameter plus all of its values.
+ * A variable and the set of values to which it has been assigned.
*/
- static class Parameter {
+ private static class Variable {
final String name;
final ImmutableList<String> values;
final int maxLength;
double stdDeviation;
- public Parameter(String name, Collection<String> values) {
+ Variable(String name, Collection<String> values) {
this.name = name;
this.values = ImmutableList.copyOf(values);
- int maxLength = name.length();
+ int maxLen = name.length();
for (String value : values) {
- maxLength = Math.max(maxLength, value.length());
+ maxLen = Math.max(maxLen, value.length());
}
- this.maxLength = maxLength;
+ this.maxLength = maxLen;
}
- String get(Run run) {
- if (vmKey.equals(name)) {
- return run.getVm();
- } else {
- return run.getParameters().get(name);
- }
+ String get(Scenario scenario) {
+ return scenario.getVariables().get(name);
}
- int index(Run run) {
- return values.indexOf(get(run));
+ int index(Scenario scenario) {
+ return values.indexOf(get(scenario));
}
boolean isInteresting() {
@@ -177,23 +171,23 @@
}
/**
- * Orders the different parameters by their standard deviation. This results
+ * Orders the different variables by their standard deviation. This results
* in an appropriate grouping of output values.
*/
- static class StandardDeviationOrdering extends Ordering<Parameter> {
- public int compare(Parameter a, Parameter b) {
+ private static class StandardDeviationOrdering extends Ordering<Variable> {
+ public int compare(Variable a, Variable b) {
return Double.compare(a.stdDeviation, b.stdDeviation);
}
}
/**
- * Orders runs by the parameters.
+ * Orders scenarios by the variables.
*/
- class ByParametersOrdering extends Ordering<Run> {
- public int compare(Run a, Run b) {
- for (Parameter parameter : parameters) {
- int aValue = parameter.values.indexOf(parameter.get(a));
- int bValue = parameter.values.indexOf(parameter.get(b));
+ private class ByVariablesOrdering extends Ordering<Scenario> {
+ public int compare(Scenario a, Scenario b) {
+ for (Variable variable : variables) {
+ int aValue = variable.values.indexOf(variable.get(a));
+ int bValue = variable.values.indexOf(variable.get(b));
int diff = aValue - bValue;
if (diff != 0) {
return diff;
@@ -206,7 +200,7 @@
void displayResults() {
printValues();
System.out.println();
- printUninterestingParameters();
+ printUninterestingVariables();
}
/**
@@ -214,33 +208,33 @@
*/
private void printValues() {
// header
- for (Parameter parameter : parameters) {
- if (parameter.isInteresting()) {
- System.out.printf("%" + parameter.maxLength + "s ", parameter.name);
+ for (Variable variable : variables) {
+ if (variable.isInteresting()) {
+ System.out.printf("%" + variable.maxLength + "s ", variable.name);
}
}
System.out.printf("%" + measurementColumnLength + "s logarithmic runtime%n", units);
// rows
String numbersFormat = "%" + measurementColumnLength + "." + decimalDigits + "f %s%n";
- for (Run run : runs) {
- for (Parameter parameter : parameters) {
- if (parameter.isInteresting()) {
- System.out.printf("%" + parameter.maxLength + "s ", parameter.get(run));
+ for (Scenario scenario : scenarios) {
+ for (Variable variable : variables) {
+ if (variable.isInteresting()) {
+ System.out.printf("%" + variable.maxLength + "s ", variable.get(scenario));
}
}
- double measurement = result.getMeasurements().get(run);
+ double measurement = run.getMeasurements().get(scenario);
System.out.printf(numbersFormat, measurement / divideBy, bargraph(measurement));
}
}
/**
- * Prints parameters with only one unique value.
+ * Prints variables with only one unique value.
*/
- private void printUninterestingParameters() {
- for (Parameter parameter : parameters) {
- if (!parameter.isInteresting()) {
- System.out.println(parameter.name + ": " + Iterables.getOnlyElement(parameter.values));
+ private void printUninterestingVariables() {
+ for (Variable variable : variables) {
+ if (!variable.isInteresting()) {
+ System.out.println(variable.name + ": " + Iterables.getOnlyElement(variable.values));
}
}
}
@@ -250,17 +244,27 @@
* value.
*/
private String bargraph(double value) {
- int numLinearChars = (int) ((value / maxValue) * bargraphWidth);
+ int numLinearChars = floor(value / maxValue * bargraphWidth);
double logValue = Math.log(value);
- int numChars = (int) ((logValue / logMaxValue) * bargraphWidth);
- StringBuilder result = new StringBuilder(numChars);
+ int numChars = floor(logValue / logMaxValue * bargraphWidth);
+ StringBuilder sb = new StringBuilder(numChars);
for (int i = 0; i < numLinearChars; i++) {
- result.append("X");
+ sb.append("X");
}
for (int i = numLinearChars; i < numChars; i++) {
- result.append("|");
+ sb.append("|");
}
- return result.toString();
+ return sb.toString();
+ }
+
+ @SuppressWarnings("NumericCastThatLosesPrecision")
+ private static int floor(double d) {
+ return (int) d;
+ }
+
+ @SuppressWarnings("NumericCastThatLosesPrecision")
+ private static int ceil(double d) {
+ return (int) Math.ceil(d);
}
}
diff --git a/src/com/google/caliper/InProcessRunner.java b/src/com/google/caliper/InProcessRunner.java
new file mode 100644
index 0000000..33e9e00
--- /dev/null
+++ b/src/com/google/caliper/InProcessRunner.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.caliper;
+
+import com.google.caliper.UserException.CantCustomizeInProcessVmException;
+import com.google.caliper.UserException.ExceptionFromUserCodeException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Executes a benchmark in the current VM.
+ */
+final class InProcessRunner {
+
+ public void run(String... args) {
+ Arguments arguments = Arguments.parse(args);
+
+ if (!arguments.getUserVms().isEmpty()) {
+ throw new CantCustomizeInProcessVmException();
+ }
+
+ ScenarioSelection scenarioSelection = new ScenarioSelection(arguments);
+
+ PrintStream resultStream = System.out;
+ System.setOut(nullPrintStream());
+ System.setErr(nullPrintStream());
+
+ try {
+ Caliper caliper = new Caliper(arguments.getWarmupMillis(), arguments.getRunMillis());
+
+ for (Scenario scenario : scenarioSelection.select()) {
+ TimedRunnable timedRunnable = scenarioSelection.createBenchmark(scenario);
+ double warmupNanosPerTrial = caliper.warmUp(timedRunnable);
+ double nanosPerTrial = caliper.run(timedRunnable, warmupNanosPerTrial);
+ resultStream.println(nanosPerTrial);
+ }
+ } catch (Exception e) {
+ throw new ExceptionFromUserCodeException(e);
+ }
+ }
+
+ public static void main(String... args) {
+ try {
+ new InProcessRunner().run(args);
+ } catch (UserException e) {
+ e.display(); // TODO: send this to the host process
+ System.exit(1);
+ }
+ }
+
+ public PrintStream nullPrintStream() {
+ return new PrintStream(new OutputStream() {
+ public void write(int b) throws IOException {}
+ });
+ }
+}
diff --git a/src/com/google/caliper/Param.java b/src/com/google/caliper/Param.java
index 28d3588..bea0269 100644
--- a/src/com/google/caliper/Param.java
+++ b/src/com/google/caliper/Param.java
@@ -26,4 +26,11 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
-public @interface Param {}
+public @interface Param {
+ /**
+ * One or more default values, as strings, that this parameter should be given if none are
+ * specified on the command line. If values are specified on the command line, the defaults given
+ * here are all ignored.
+ */
+ String[] value() default {};
+}
diff --git a/src/com/google/caliper/Parameter.java b/src/com/google/caliper/Parameter.java
index 1ba77b5..caca252 100644
--- a/src/com/google/caliper/Parameter.java
+++ b/src/com/google/caliper/Parameter.java
@@ -16,8 +16,19 @@
package com.google.caliper;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
/**
* A parameter in a {@link SimpleBenchmark}.
@@ -35,22 +46,35 @@
*/
public static Map<String, Parameter<?>> forClass(Class<? extends Benchmark> suiteClass) {
Map<String, Parameter<?>> parameters = new TreeMap<String, Parameter<?>>();
- for (final Field field : suiteClass.getDeclaredFields()) {
+ for (Field field : suiteClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Param.class)) {
field.setAccessible(true);
- Parameter parameter = Parameter.forField(suiteClass, field);
+ Parameter<?> parameter = forField(suiteClass, field);
parameters.put(parameter.getName(), parameter);
}
}
return parameters;
}
- public static Parameter forField(
+ private static Parameter<?> forField(
Class<? extends Benchmark> suiteClass, final Field field) {
- Parameter result = null;
+ // First check for String values on the annotation itself
+ final Object[] defaults = field.getAnnotation(Param.class).value();
+ if (defaults.length > 0) {
+ return new Parameter<Object>(field) {
+ @Override public Collection<Object> values() throws Exception {
+ return Arrays.asList(defaults);
+ }
+ };
+ // TODO: or should we continue so we can give an error/warning if params are also give in a
+ // method or field?
+ }
+
+ Parameter<?> result = null;
Type returnType = null;
Member member = null;
+ // Now check for a fooValues() method
try {
final Method valuesMethod = suiteClass.getDeclaredMethod(field.getName() + "Values");
valuesMethod.setAccessible(true);
@@ -58,13 +82,14 @@
returnType = valuesMethod.getGenericReturnType();
result = new Parameter<Object>(field) {
@SuppressWarnings("unchecked") // guarded below
- public Collection<Object> values() throws Exception {
+ @Override public Collection<Object> values() throws Exception {
return (Collection<Object>) valuesMethod.invoke(null);
}
};
} catch (NoSuchMethodException ignored) {
}
+ // Now check for a fooValues field
try {
final Field valuesField = suiteClass.getDeclaredField(field.getName() + "Values");
valuesField.setAccessible(true);
@@ -75,38 +100,60 @@
returnType = valuesField.getGenericType();
result = new Parameter<Object>(field) {
@SuppressWarnings("unchecked") // guarded below
- public Collection<Object> values() throws Exception {
+ @Override public Collection<Object> values() throws Exception {
return (Collection<Object>) valuesField.get(null);
}
};
} catch (NoSuchFieldException ignored) {
}
+ if (member != null && !Modifier.isStatic(member.getModifiers())) {
+ throw new ConfigurationException("Values member must be static " + member);
+ }
+
+ // If there isn't a values member but the parameter is an enum, we default
+ // to EnumSet.allOf.
+ if (member == null && field.getType().isEnum()) {
+ returnType = Collection.class;
+ result = new Parameter<Object>(field) {
+ // TODO: figure out the simplest way to make this compile and be green in IDEA too
+ @SuppressWarnings({"unchecked", "RawUseOfParameterizedType", "RedundantCast"})
+ // guarded above
+ @Override public Collection<Object> values() throws Exception {
+ Set<Enum> set = EnumSet.allOf((Class<Enum>) field.getType());
+ return (Collection) set;
+ }
+ };
+ }
+
if (result == null) {
- throw new ConfigurationException("No values member defined for " + field);
- }
-
- if (!Modifier.isStatic(member.getModifiers())) {
- throw new ConfigurationException("Values member must be static " + member);
- }
-
- // validate return type
- boolean valid = false;
- if (returnType instanceof ParameterizedType) {
- ParameterizedType type = (ParameterizedType) returnType;
- if (type.getRawType() == Collection.class) {
- valid = true;
- }
- }
-
- if (!valid) {
+ return new Parameter<Object>(field) {
+ @Override public Collection<Object> values() {
+ // TODO: need tests to make sure this fails properly when no cmdline params given and
+ // works properly when they are given
+ return Collections.emptySet();
+ }
+ };
+ } else if (!isValidReturnType(returnType)) {
throw new ConfigurationException("Invalid return type " + returnType
+ " for values member " + member + "; must be Collection");
}
-
return result;
}
+ private static boolean isValidReturnType(Type returnType) {
+ if (returnType == Collection.class) {
+ return true;
+ }
+ if (returnType instanceof ParameterizedType) {
+ ParameterizedType type = (ParameterizedType) returnType;
+ if (type.getRawType() == Collection.class) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Sets the value of this property to the specified value for the given suite.
*/
@@ -129,7 +176,7 @@
/**
* Returns the field's name.
*/
- public String getName() {
+ String getName() {
return field.getName();
}
-}
\ No newline at end of file
+}
diff --git a/src/com/google/caliper/Result.java b/src/com/google/caliper/Result.java
deleted file mode 100644
index 888a9f4..0000000
--- a/src/com/google/caliper/Result.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (C) 2009 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.caliper;
-
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
-/**
- * The complete result of a benchmark suite run.
- */
-final class Result {
-
- private final ImmutableMap<Run, Double> measurements;
-
- public Result(Map<Run, Double> measurements) {
- this.measurements = ImmutableMap.copyOf(measurements);
- }
-
- public ImmutableMap<Run, Double> getMeasurements() {
- return measurements;
- }
-}
diff --git a/src/com/google/caliper/Run.java b/src/com/google/caliper/Run.java
index a9109de..f2e71de 100644
--- a/src/com/google/caliper/Run.java
+++ b/src/com/google/caliper/Run.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,33 +16,77 @@
package com.google.caliper;
-import com.google.common.collect.ImmutableMap;
-
-import java.lang.reflect.Method;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.LinkedHashMap;
import java.util.Map;
/**
- * A configured benchmark.
+ * The complete result of a benchmark suite run.
+ *
+ * <p>Gwt-safe.
*/
-final class Run {
+public final class Run
+ implements Serializable /* for GWT Serialization */ {
- private final ImmutableMap<String, String> parameters;
- private final String vm;
+ private /*final*/ Map<Scenario, Double> measurements;
+ private /*final*/ String benchmarkName;
+ private /*final*/ String executedByUuid;
+ private /*final*/ long executedTimestamp;
- public Run(Map<String, String> parameters, String vm) {
- this.parameters = ImmutableMap.copyOf(parameters);
- this.vm = vm;
+ // TODO: add more run properites such as checksums of the executed code
+
+ public Run(Map<Scenario, Double> measurements,
+ String benchmarkName, String executedByUuid, Date executedTimestamp) {
+ if (benchmarkName == null || executedByUuid == null || executedTimestamp == null) {
+ throw new NullPointerException();
+ }
+
+ this.measurements = new LinkedHashMap<Scenario, Double>(measurements);
+ this.benchmarkName = benchmarkName;
+ this.executedByUuid = executedByUuid;
+ this.executedTimestamp = executedTimestamp.getTime();
}
- public ImmutableMap<String, String> getParameters() {
- return parameters;
+ public Map<Scenario, Double> getMeasurements() {
+ return measurements;
}
- public String getVm() {
- return vm;
+ public String getBenchmarkName() {
+ return benchmarkName;
+ }
+
+ public String getExecutedByUuid() {
+ return executedByUuid;
+ }
+
+ public Date getExecutedTimestamp() {
+ return new Date(executedTimestamp);
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o instanceof Run) {
+ Run that = (Run) o;
+ return measurements.equals(that.measurements)
+ && benchmarkName.equals(that.benchmarkName)
+ && executedByUuid.equals(that.executedByUuid)
+ && executedTimestamp == that.executedTimestamp;
+ }
+
+ return false;
+ }
+
+ @Override public int hashCode() {
+ int result = measurements.hashCode();
+ result = result * 37 + benchmarkName.hashCode();
+ result = result * 37 + executedByUuid.hashCode();
+ result = result * 37 + (int) ((executedTimestamp >> 32) ^ executedTimestamp);
+ return result;
}
@Override public String toString() {
- return "Run" + parameters;
+ return measurements.toString();
}
+
+ private Run() {} // for GWT Serialization
}
diff --git a/src/com/google/caliper/Runner.java b/src/com/google/caliper/Runner.java
index 72442db..e359df8 100644
--- a/src/com/google/caliper/Runner.java
+++ b/src/com/google/caliper/Runner.java
@@ -16,180 +16,113 @@
package com.google.caliper;
+import com.google.caliper.UserException.ExceptionFromUserCodeException;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Multimap;
-
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ObjectArrays;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.UUID;
/**
* Creates, executes and reports benchmark runs.
*/
public final class Runner {
- private String suiteClassName;
- private Benchmark suite;
-
- /** Effective parameters to run in the benchmark. */
- private Multimap<String, String> parameters = LinkedHashMultimap.create();
-
- /** JVMs to run in the benchmark */
- private Set<String> userVms = new LinkedHashSet<String>();
+ /** Command line arguments to the process */
+ private Arguments arguments;
+ private ScenarioSelection scenarioSelection;
/**
- * Parameter values specified by the user on the command line. Parameters with
- * no value in this multimap will get their values from the benchmark suite.
+ * Returns the UUID of the executing host. Multiple runs by the same user on
+ * the same machine should yield the same result.
*/
- private Multimap<String, String> userParameters = LinkedHashMultimap.create();
-
- /**
- * True if each benchmark should run in process.
- */
- private boolean inProcess;
-
- private long warmupMillis = 5000;
- private long runMillis = 5000;
-
- /**
- * Sets the named parameter to the specified value. This value will replace
- * the benchmark suite's default values for the parameter. Multiple calls to
- * this method will cause benchmarks for each value to be run.
- */
- void setParameter(String name, String value) {
- userParameters.put(name, value);
- }
-
- private void prepareSuite() {
+ private String getExecutedByUuid() {
try {
- @SuppressWarnings("unchecked") // guarded by the if statement that follows
- Class<? extends Benchmark> suiteClass
- = (Class<? extends Benchmark>) Class.forName(suiteClassName);
- if (!Benchmark.class.isAssignableFrom(suiteClass)) {
- throw new ConfigurationException(suiteClass + " is not a benchmark suite.");
+ File dotCaliperRc = new File(System.getProperty("user.home"), ".caliperrc");
+ Properties properties = new Properties();
+ if (dotCaliperRc.exists()) {
+ properties.load(new FileInputStream(dotCaliperRc));
}
- Constructor<? extends Benchmark> constructor = suiteClass.getDeclaredConstructor();
- suite = constructor.newInstance();
- } catch (InvocationTargetException e) {
- throw new ExecutionException(e.getCause());
- } catch (Exception e) {
- throw new ConfigurationException(e);
+ String userUuid = properties.getProperty("userUuid");
+ if (userUuid == null) {
+ userUuid = UUID.randomUUID().toString();
+ properties.setProperty("userUuid", userUuid);
+ properties.store(new FileOutputStream(dotCaliperRc), "");
+ }
+
+ return userUuid;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
- private void prepareParameters() {
- for (String key : suite.parameterNames()) {
- // first check if the user has specified values
- Collection<String> userValues = userParameters.get(key);
- if (!userValues.isEmpty()) {
- parameters.putAll(key, userValues);
- // TODO: type convert 'em to validate?
+ public void run(String... args) {
+ this.arguments = Arguments.parse(args);
+ this.scenarioSelection = new ScenarioSelection(arguments);
+ Run run = runOutOfProcess();
+ new ConsoleReport(run).displayResults();
+ postResults(run);
+ }
- } else { // otherwise use the default values from the suite
- Set<String> values = suite.parameterValues(key);
- if (values.isEmpty()) {
- throw new ConfigurationException(key + " has no values");
- }
- parameters.putAll(key, values);
+ private void postResults(Run run) {
+ String postHost = arguments.getPostHost();
+ if ("none".equals(postHost)) {
+ return;
+ }
+
+ try {
+ URL url = new URL(postHost + run.getExecutedByUuid() + "/" + run.getBenchmarkName());
+ HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ urlConnection.setDoOutput(true);
+ Xml.runToXml(run, urlConnection.getOutputStream());
+ if (urlConnection.getResponseCode() == 200) {
+ System.out.println("");
+ System.out.println("View current and previous benchmark results online:");
+ System.out.println(" " + url);
+ return;
}
+
+ System.out.println("Posting to " + postHost + " failed: "
+ + urlConnection.getResponseMessage());
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(urlConnection.getInputStream()));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ System.out.println(line);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
- private ImmutableSet<String> defaultVms() {
- return "Dalvik".equals(System.getProperty("java.vm.name"))
- ? ImmutableSet.of("dalvikvm")
- : ImmutableSet.of("java");
- }
-
- /**
- * Returns a complete set of runs with every combination of values and
- * benchmark classes.
- */
- private List<Run> createRuns() throws Exception {
- List<RunBuilder> builders = new ArrayList<RunBuilder>();
-
- // create runs for each VMs
- Set<String> vms = userVms.isEmpty()
- ? defaultVms()
- : userVms;
- for (String vm : vms) {
- RunBuilder runBuilder = new RunBuilder();
- runBuilder.vm = vm;
- builders.add(runBuilder);
- }
-
- for (Map.Entry<String, Collection<String>> parameter : parameters.asMap().entrySet()) {
- Iterator<String> values = parameter.getValue().iterator();
- if (!values.hasNext()) {
- throw new ConfigurationException("Not enough values for " + parameter);
- }
-
- String key = parameter.getKey();
-
- String firstValue = values.next();
- for (RunBuilder builder : builders) {
- builder.parameters.put(key, firstValue);
- }
-
- // multiply the size of the specs by the number of alternate values
- int size = builders.size();
- while (values.hasNext()) {
- String alternate = values.next();
- for (int s = 0; s < size; s++) {
- RunBuilder copy = builders.get(s).copy();
- copy.parameters.put(key, alternate);
- builders.add(copy);
- }
- }
- }
-
- List<Run> result = new ArrayList<Run>();
- for (RunBuilder builder : builders) {
- result.add(builder.build());
- }
-
- return result;
- }
-
- static class RunBuilder {
- Map<String, String> parameters = new LinkedHashMap<String, String>();
- String vm;
-
- RunBuilder copy() {
- RunBuilder result = new RunBuilder();
- result.parameters.putAll(parameters);
- result.vm = vm;
- return result;
- }
-
- public Run build() {
- return new Run(parameters, vm);
- }
- }
-
- private double executeForked(Run run) {
+ private double executeForked(Scenario scenario) {
ProcessBuilder builder = new ProcessBuilder();
List<String> command = builder.command();
- command.addAll(Arrays.asList(run.getVm().split("\\s+")));
+ command.addAll(Arrays.asList(scenario.getVariables().get(Scenario.VM_KEY).split("\\s+")));
command.add("-cp");
command.add(System.getProperty("java.class.path"));
- command.add(Runner.class.getName());
+ command.add(InProcessRunner.class.getName());
command.add("--warmupMillis");
- command.add(String.valueOf(warmupMillis));
+ command.add(String.valueOf(arguments.getWarmupMillis()));
command.add("--runMillis");
- command.add(String.valueOf(runMillis));
- command.add("--inProcess");
- for (Map.Entry<String, String> entry : run.getParameters().entrySet()) {
+ command.add(String.valueOf(arguments.getRunMillis()));
+ for (Entry<String, String> entry : scenario.getParameters().entrySet()) {
command.add("-D" + entry.getKey() + "=" + entry.getValue());
}
- command.add(suiteClassName);
+ command.add(arguments.getSuiteClassName());
BufferedReader reader = null;
try {
@@ -202,7 +135,7 @@
Double nanosPerTrial = null;
try {
nanosPerTrial = Double.valueOf(firstLine);
- } catch (NumberFormatException e) {
+ } catch (NumberFormatException ignore) {
}
String anotherLine = reader.readLine();
@@ -229,163 +162,63 @@
}
}
- private Result runOutOfProcess() {
- ImmutableMap.Builder<Run, Double> resultsBuilder = ImmutableMap.builder();
+ // TODO: check if this is platform-independent
+ @SuppressWarnings("HardcodedLineSeparator")
+ private static final String RETURN = "\r";
+
+ private Run runOutOfProcess() {
+ String executedByUuid = getExecutedByUuid();
+ Date executedDate = new Date();
+ Builder<Scenario, Double> resultsBuilder = ImmutableMap.builder();
try {
- List<Run> runs = createRuns();
+ List<Scenario> scenarios = scenarioSelection.select();
int i = 0;
- for (Run run : runs) {
- beforeRun(i++, runs.size(), run);
- double nanosPerTrial = executeForked(run);
- afterRun(nanosPerTrial);
- resultsBuilder.put(run, nanosPerTrial);
+ for (Scenario scenario : scenarios) {
+ beforeMeasurement(i++, scenarios.size(), scenario);
+ double nanosPerTrial = executeForked(scenario);
+ afterMeasurement(nanosPerTrial);
+ resultsBuilder.put(scenario, nanosPerTrial);
}
// blat out our progress bar
- System.out.print("\r");
+ System.out.print(RETURN);
for (int j = 0; j < 80; j++) {
System.out.print(" ");
}
- System.out.print("\r");
+ System.out.print(RETURN);
- return new Result(resultsBuilder.build());
+ return new Run(resultsBuilder.build(), arguments.getSuiteClassName(), executedByUuid, executedDate);
} catch (Exception e) {
- throw new ExecutionException(e);
+ throw new ExceptionFromUserCodeException(e);
}
}
- private void beforeRun(int index, int total, Run run) {
+ private void beforeMeasurement(int index, int total, Scenario scenario) {
double percentDone = (double) index / total;
int runStringLength = 63; // so the total line length is 80
- String runString = String.valueOf(run);
+ String runString = String.valueOf(scenario);
if (runString.length() > runStringLength) {
runString = runString.substring(0, runStringLength);
}
- System.out.printf("\r%2.0f%% %-" + runStringLength + "s",
+ System.out.printf(RETURN + "%2.0f%% %-" + runStringLength + "s",
percentDone * 100, runString);
}
- private void afterRun(double nanosPerTrial) {
+ private void afterMeasurement(double nanosPerTrial) {
System.out.printf(" %10.0fns", nanosPerTrial);
}
- private void runInProcess() {
+ public static void main(String... args) {
try {
- Caliper caliper = new Caliper(warmupMillis, runMillis);
-
- for (Run run : createRuns()) {
- double result;
- TimedRunnable timedRunnable = suite.createBenchmark(run.getParameters());
- double warmupNanosPerTrial = caliper.warmUp(timedRunnable);
- result = caliper.run(timedRunnable, warmupNanosPerTrial);
- double nanosPerTrial = result;
- System.out.println(nanosPerTrial);
- }
- } catch (Exception e) {
- throw new ExecutionException(e);
+ new Runner().run(args);
+ } catch (UserException e) {
+ e.display();
+ System.exit(1);
}
}
- private boolean parseArgs(String[] args) throws Exception {
- for (int i = 0; i < args.length; i++) {
- if ("--help".equals(args[i])) {
- return false;
-
- } else if ("--inProcess".equals(args[i])) {
- inProcess = true;
-
- } else if (args[i].startsWith("-D")) {
- int equalsSign = args[i].indexOf('=');
- if (equalsSign == -1) {
- System.out.println("Malformed parameter " + args[i]);
- return false;
- }
- String name = args[i].substring(2, equalsSign);
- String value = args[i].substring(equalsSign + 1);
- setParameter(name, value);
-
- } else if ("--warmupMillis".equals(args[i])) {
- warmupMillis = Long.parseLong(args[++i]);
-
- } else if ("--runMillis".equals(args[i])) {
- runMillis = Long.parseLong(args[++i]);
-
- } else if ("--vm".equals(args[i])) {
- userVms.add(args[++i]);
-
- } else if (args[i].startsWith("-")) {
- System.out.println("Unrecognized option: " + args[i]);
- return false;
-
- } else {
- if (suiteClassName != null) {
- System.out.println("Too many benchmark classes!");
- return false;
- }
- suiteClassName = args[i];
- }
- }
-
- if (inProcess && !userVms.isEmpty()) {
- System.out.println("Cannot customize VM when running in process");
- return false;
- }
-
- if (suiteClassName == null) {
- System.out.println("No benchmark class provided.");
- return false;
- }
-
- return true;
- }
-
- private void printUsage() {
- System.out.println("Usage: Runner [OPTIONS...] <benchmark>");
- System.out.println();
- System.out.println(" <benchmark>: a benchmark class or suite");
- System.out.println();
- System.out.println("OPTIONS");
- System.out.println();
- System.out.println(" --D<param>=<value>: fix a benchmark parameter to a given value.");
- System.out.println(" When multiple values for the same parameter are given (via");
- System.out.println(" multiple --Dx=y args), all supplied values are used.");
- System.out.println();
- System.out.println(" --inProcess: run the benchmark in the same JVM rather than spawning");
- System.out.println(" another with the same classpath. By default each benchmark is");
- System.out.println(" run in a separate VM");
- System.out.println();
- System.out.println(" --warmupMillis <millis>: duration to warmup each benchmark");
- System.out.println();
- System.out.println(" --runMillis <millis>: duration to execute each benchmark");
- System.out.println();
- System.out.println(" --vm <vm>: executable to test benchmark on");
-
- // adding new options? don't forget to update executeForked()
- }
-
- public static void main(String... args) throws Exception { // TODO: cleaner error reporting
- Runner runner = new Runner();
- if (!runner.parseArgs(args)) {
- runner.printUsage();
- return;
- }
-
- runner.prepareSuite();
- runner.prepareParameters();
- if (runner.inProcess) {
- runner.runInProcess();
- return;
- }
-
- Result result = runner.runOutOfProcess();
- new ConsoleReport(result).displayResults();
- }
-
- public static void main(Class<? extends Benchmark> suite, String... args) throws Exception {
- String[] argsWithSuiteName = new String[args.length + 1];
- System.arraycopy(args, 0, argsWithSuiteName, 0, args.length);
- argsWithSuiteName[args.length] = suite.getName();
- main(argsWithSuiteName);
+ public static void main(Class<? extends Benchmark> suite, String... args) {
+ main(ObjectArrays.concat(args, suite.getName()));
}
}
diff --git a/src/com/google/caliper/Scenario.java b/src/com/google/caliper/Scenario.java
new file mode 100644
index 0000000..3fd06e4
--- /dev/null
+++ b/src/com/google/caliper/Scenario.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.caliper;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A configured benchmark.
+ *
+ * <p>Gwt-safe.
+ */
+public final class Scenario
+ implements Serializable /* for GWT */ {
+
+ static final String VM_KEY = "vm";
+
+ /**
+ * The subset of variable names that are managed by the system. It is an error
+ * to create a parameter with the same name as one of these variables.
+ */
+ static final Set<String> SYSTEM_VARIABLES = new HashSet<String>(Arrays.asList(VM_KEY));
+
+ private /*final*/ Map<String, String> variables;
+
+ public Scenario(Map<String, String> variables) {
+ this.variables = new LinkedHashMap<String, String>(variables);
+ }
+
+ public Map<String, String> getVariables() {
+ return variables;
+ }
+
+ /**
+ * Returns the user-specified parameters. This is the (possibly-empty) set of
+ * variables that may be varied from scenario to scenario in the same
+ * environment.
+ */
+ public Map<String, String> getParameters() {
+ Map<String, String> result = new LinkedHashMap<String, String>();
+ for (Map.Entry<String, String> entry : variables.entrySet()) {
+ if (!SYSTEM_VARIABLES.contains(entry.getKey())) {
+ result.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ return o instanceof Scenario
+ && ((Scenario) o).getVariables().equals(variables);
+ }
+
+ @Override public int hashCode() {
+ return variables.hashCode();
+ }
+
+ @Override public String toString() {
+ return "Scenario" + variables;
+ }
+
+ private Scenario() {} // for GWT
+}
diff --git a/src/com/google/caliper/ScenarioSelection.java b/src/com/google/caliper/ScenarioSelection.java
new file mode 100644
index 0000000..7814818
--- /dev/null
+++ b/src/com/google/caliper/ScenarioSelection.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.caliper;
+
+import com.google.caliper.UserException.AbstractBenchmarkException;
+import com.google.caliper.UserException.DoesntImplementBenchmarkException;
+import com.google.caliper.UserException.ExceptionFromUserCodeException;
+import com.google.caliper.UserException.NoParameterlessConstructorException;
+import com.google.caliper.UserException.NoSuchClassException;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Figures out which scenarios to benchmark given a benchmark suite, set of user
+ * parameters, and set of user VMs.
+ */
+public final class ScenarioSelection {
+
+ private final String suiteClassName;
+ private final Multimap<String, String> userParameters;
+ private final Set<String> userVms;
+
+ private Benchmark suite;
+
+ /** Effective parameters to run in the benchmark. */
+ private final Multimap<String, String> parameters = LinkedHashMultimap.create();
+
+ public ScenarioSelection(Arguments arguments) {
+ this(arguments.getSuiteClassName(), arguments.getUserParameters(), arguments.getUserVms());
+ }
+
+ public ScenarioSelection(String suiteClassName,
+ Multimap<String, String> userParameters, Set<String> userVms) {
+ this.suiteClassName = suiteClassName;
+ this.userParameters = userParameters;
+ this.userVms = userVms;
+ }
+
+ /**
+ * Returns the selected scenarios for this benchmark.
+ */
+ public List<Scenario> select() {
+ prepareSuite();
+ prepareParameters();
+ return createScenarios();
+ }
+
+ public TimedRunnable createBenchmark(Scenario scenario) {
+ return suite.createBenchmark(scenario.getParameters());
+ }
+
+ private void prepareSuite() {
+ Class<?> benchmarkClass;
+ try {
+ benchmarkClass = getClassByName(suiteClassName);
+ } catch (ExceptionInInitializerError e) {
+ throw new ExceptionFromUserCodeException(e.getCause());
+ } catch (ClassNotFoundException ignored) {
+ throw new NoSuchClassException(suiteClassName);
+ }
+
+ Object s;
+ try {
+ Constructor<?> constructor = benchmarkClass.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ s = constructor.newInstance();
+ } catch (InstantiationException ignore) {
+ throw new AbstractBenchmarkException(benchmarkClass);
+ } catch (NoSuchMethodException ignore) {
+ throw new NoParameterlessConstructorException(benchmarkClass);
+ } catch (IllegalAccessException impossible) {
+ throw new AssertionError(impossible); // shouldn't happen since we setAccessible(true)
+ } catch (InvocationTargetException e) {
+ throw new ExceptionFromUserCodeException(e.getCause());
+ }
+
+ if (s instanceof Benchmark) {
+ this.suite = (Benchmark) s;
+ } else {
+ throw new DoesntImplementBenchmarkException(benchmarkClass);
+ }
+ }
+
+ private static Class<?> getClassByName(String className) throws ClassNotFoundException {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException ignored) {
+ // try replacing the last dot with a $, in case that helps
+ // example: tutorial.Tutorial.Benchmark1 becomes tutorial.Tutorial$Benchmark1
+ // amusingly, the $ character means three different things in this one line alone
+ String newName = className.replaceFirst("\\.([^.]+)$", "\\$$1");
+ return Class.forName(newName);
+ }
+ }
+
+ private void prepareParameters() {
+ for (String key : suite.parameterNames()) {
+ // first check if the user has specified values
+ Collection<String> userValues = userParameters.get(key);
+ if (!userValues.isEmpty()) {
+ parameters.putAll(key, userValues);
+ // TODO: type convert 'em to validate?
+
+ } else { // otherwise use the default values from the suite
+ Set<String> values = suite.parameterValues(key);
+ if (values.isEmpty()) {
+ throw new ConfigurationException(key + " has no values");
+ }
+ parameters.putAll(key, values);
+ }
+ }
+ }
+
+ private ImmutableSet<String> defaultVms() {
+ return "Dalvik".equals(System.getProperty("java.vm.name"))
+ ? ImmutableSet.of("dalvikvm")
+ : ImmutableSet.of("java");
+ }
+
+ /**
+ * Returns a complete set of scenarios with every combination of values and
+ * benchmark classes.
+ */
+ private List<Scenario> createScenarios() {
+ List<ScenarioBuilder> builders = new ArrayList<ScenarioBuilder>();
+
+ // create scenarios for each VM
+ Set<String> vms = userVms.isEmpty()
+ ? defaultVms()
+ : userVms;
+ for (String vm : vms) {
+ ScenarioBuilder scenarioBuilder = new ScenarioBuilder();
+ scenarioBuilder.parameters.put(Scenario.VM_KEY, vm);
+ builders.add(scenarioBuilder);
+ }
+
+ for (Entry<String, Collection<String>> parameter : parameters.asMap().entrySet()) {
+ Iterator<String> values = parameter.getValue().iterator();
+ if (!values.hasNext()) {
+ throw new ConfigurationException("Not enough values for " + parameter);
+ }
+
+ String key = parameter.getKey();
+
+ String firstValue = values.next();
+ for (ScenarioBuilder builder : builders) {
+ builder.parameters.put(key, firstValue);
+ }
+
+ // multiply the size of the specs by the number of alternate values
+ int size = builders.size();
+ while (values.hasNext()) {
+ String alternate = values.next();
+ for (int s = 0; s < size; s++) {
+ ScenarioBuilder copy = builders.get(s).copy();
+ copy.parameters.put(key, alternate);
+ builders.add(copy);
+ }
+ }
+ }
+
+ List<Scenario> result = new ArrayList<Scenario>();
+ for (ScenarioBuilder builder : builders) {
+ result.add(builder.build());
+ }
+
+ return result;
+ }
+
+ private static class ScenarioBuilder {
+ final Map<String, String> parameters = new LinkedHashMap<String, String>();
+
+ ScenarioBuilder copy() {
+ ScenarioBuilder result = new ScenarioBuilder();
+ result.parameters.putAll(parameters);
+ return result;
+ }
+
+ public Scenario build() {
+ return new Scenario(parameters);
+ }
+ }
+}
diff --git a/src/com/google/caliper/SimpleBenchmark.java b/src/com/google/caliper/SimpleBenchmark.java
index 8d2d4b1..31ff6c9 100644
--- a/src/com/google/caliper/SimpleBenchmark.java
+++ b/src/com/google/caliper/SimpleBenchmark.java
@@ -16,12 +16,11 @@
package com.google.caliper;
+import com.google.caliper.UserException.ExceptionFromUserCodeException;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
@@ -88,34 +87,31 @@
return methods.keySet();
}
+ Parameter<?> parameter = parameters.get(parameterName);
+ if (parameter == null) {
+ throw new IllegalArgumentException();
+ }
try {
- TypeConverter typeConverter = new TypeConverter();
- Parameter<?> parameter = parameters.get(parameterName);
- if (parameter == null) {
- throw new IllegalArgumentException();
- }
Collection<?> values = parameter.values();
- Type type = parameter.getType();
ImmutableSet.Builder<String> result = ImmutableSet.builder();
for (Object value : values) {
- result.add(typeConverter.toString(value, type));
+ result.add(String.valueOf(value));
}
return result.build();
} catch (Exception e) {
- throw new ExecutionException(e);
+ throw new ExceptionFromUserCodeException(e);
}
}
public TimedRunnable createBenchmark(Map<String, String> parameterValues) {
- TypeConverter typeConverter = new TypeConverter();
-
if (!parameterNames().equals(parameterValues.keySet())) {
throw new IllegalArgumentException("Invalid parameters specified. Expected "
+ parameterNames() + " but was " + parameterValues.keySet());
}
try {
+ @SuppressWarnings({"ClassNewInstance"}) // can throw any Exception, so we catch all Exceptions
final SimpleBenchmark copyOfSelf = getClass().newInstance();
final Method method = methods.get(parameterValues.get("benchmark"));
@@ -125,8 +121,8 @@
continue;
}
- Parameter parameter = parameters.get(parameterName);
- Object value = typeConverter.fromString(entry.getValue(), parameter.getType());
+ Parameter<?> parameter = parameters.get(parameterName);
+ Object value = TypeConverter.fromString(entry.getValue(), parameter.getType());
parameter.set(copyOfSelf, value);
}
copyOfSelf.setUp();
@@ -138,7 +134,7 @@
};
} catch (Exception e) {
- throw new ExecutionException(e);
+ throw new ExceptionFromUserCodeException(e);
}
}
@@ -148,7 +144,7 @@
*/
private Map<String, Method> createTimedMethods() {
ImmutableMap.Builder<String, Method> result = ImmutableMap.builder();
- for (final Method method : getClass().getDeclaredMethods()) {
+ for (Method method : getClass().getDeclaredMethods()) {
int modifiers = method.getModifiers();
if (!method.getName().startsWith("time")) {
continue;
diff --git a/src/com/google/caliper/TypeConverter.java b/src/com/google/caliper/TypeConverter.java
index 73300ec..29d00ea 100644
--- a/src/com/google/caliper/TypeConverter.java
+++ b/src/com/google/caliper/TypeConverter.java
@@ -16,42 +16,44 @@
package com.google.caliper;
+import com.google.common.collect.ImmutableMap;
+import java.lang.reflect.Method;
import java.lang.reflect.Type;
+import java.util.Map;
/**
* Convert objects to and from Strings.
*/
-class TypeConverter {
+final class TypeConverter {
+ private TypeConverter() {}
- // the enum to strings conversion is manually checked
+ public static Object fromString(String value, Type type) {
+ Class<?> c = wrap((Class<?>) type);
+ try {
+ Method m = c.getMethod("valueOf", String.class);
+ return m.invoke(null, value);
+ } catch (Exception e) {
+ throw new UnsupportedOperationException(
+ "Cannot convert " + value + " of type " + type, e);
+ }
+ }
+
+ // safe because both Long.class and long.class are of type Class<Long>
@SuppressWarnings("unchecked")
- public Object fromString(String value, Type type) {
- if (type instanceof Class) {
- Class<?> c = (Class<?>) type;
- if (c.isEnum()) {
- return Enum.valueOf((Class) c, value);
- } else if (type == Double.class || type == double.class) {
- return Double.valueOf(value);
- } else if (type == Integer.class || type == int.class) {
- return Integer.valueOf(value);
- }
- }
- throw new UnsupportedOperationException(
- "Cannot convert " + value + " of type " + type);
+ private static <T> Class<T> wrap(Class<T> c) {
+ return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c;
}
- public String toString(Object value, Type type) {
- if (type instanceof Class) {
- Class<?> c = (Class<?>) type;
- if (c.isEnum()) {
- return value.toString();
- } else if (type == Double.class || type == double.class) {
- return value.toString();
- } else if (type == Integer.class || type == int.class) {
- return value.toString();
- }
- }
- throw new UnsupportedOperationException(
- "Cannot convert " + value + " of type " + type);
- }
+ private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS
+ = new ImmutableMap.Builder<Class<?>, Class<?>>()
+ .put(boolean.class, Boolean.class)
+ .put(byte.class, Byte.class)
+ .put(char.class, Character.class)
+ .put(double.class, Double.class)
+ .put(float.class, Float.class)
+ .put(int.class, Integer.class)
+ .put(long.class, Long.class)
+ .put(short.class, Short.class)
+ .put(void.class, Void.class)
+ .build();
}
diff --git a/src/com/google/caliper/UserException.java b/src/com/google/caliper/UserException.java
new file mode 100644
index 0000000..66fb8e3
--- /dev/null
+++ b/src/com/google/caliper/UserException.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.caliper;
+
+import java.util.Arrays;
+
+/**
+ * Signifies a problem that should be explained in user-friendly terms on the command line, without
+ * a confusing stack trace, and optionally followed by a usage summary.
+ */
+@SuppressWarnings("serial") // never going to serialize these... right?
+public abstract class UserException extends RuntimeException {
+ protected final String error;
+
+ protected UserException(String error) {
+ this.error = error;
+ }
+
+ public abstract void display();
+
+ // - - - -
+
+ public abstract static class ErrorInUsageException extends UserException {
+ protected ErrorInUsageException(String error) {
+ super(error);
+ }
+
+ @Override public void display() {
+ if (error != null) {
+ System.err.println("Error: " + error);
+ }
+ Arguments.printUsage();
+ }
+ }
+
+ public abstract static class ErrorInUserCodeException extends UserException {
+ private final String remedy;
+
+ protected ErrorInUserCodeException(String error, String remedy) {
+ super(error);
+ this.remedy = remedy;
+ }
+
+ @Override public void display() {
+ System.err.println("Error: " + error);
+ System.err.println("Typical Remedy: " + remedy);
+ }
+ }
+
+ // - - - -
+
+ // Not technically an error, but works nicely this way anyway
+ public static class DisplayUsageException extends ErrorInUsageException {
+ public DisplayUsageException() {
+ super(null);
+ }
+ }
+
+ public static class UnrecognizedOptionException extends ErrorInUsageException {
+ public UnrecognizedOptionException(String arg) {
+ super("Argument not recognized: " + arg);
+ }
+ }
+
+ public static class NoBenchmarkClassException extends ErrorInUsageException {
+ public NoBenchmarkClassException() {
+ super("No benchmark class specified.");
+ }
+ }
+
+ public static class MultipleBenchmarkClassesException extends ErrorInUsageException {
+ public MultipleBenchmarkClassesException(String a, String b) {
+ super("Multiple benchmark classes specified: " + Arrays.asList(a, b));
+ }
+ }
+
+ public static class MalformedParameterException extends ErrorInUsageException {
+ public MalformedParameterException(String arg) {
+ super("Malformed parameter: " + arg);
+ }
+ }
+
+ public static class CantCustomizeInProcessVmException extends ErrorInUsageException {
+ public CantCustomizeInProcessVmException() {
+ super("Can't customize VM when running in process.");
+ }
+ }
+
+ public static class NoSuchClassException extends ErrorInUsageException {
+ public NoSuchClassException(String name) {
+ super("No class named [" + name + "] was found (check CLASSPATH).");
+ }
+ }
+
+
+ public static class AbstractBenchmarkException extends ErrorInUserCodeException {
+ public AbstractBenchmarkException(Class<?> specifiedClass) {
+ super("Class [" + specifiedClass.getName() + "] is abstract.", "Specify a concrete class.");
+ }
+ }
+
+ public static class NoParameterlessConstructorException extends ErrorInUserCodeException {
+ public NoParameterlessConstructorException(Class<?> specifiedClass) {
+ super("Class [" + specifiedClass.getName() + "] has no parameterless constructor.",
+ "Remove all constructors or add a parameterless constructor.");
+ }
+ }
+
+ public static class DoesntImplementBenchmarkException extends ErrorInUserCodeException {
+ public DoesntImplementBenchmarkException(Class<?> specifiedClass) {
+ super("Class [" + specifiedClass + "] does not implement the " + Benchmark.class.getName()
+ + " interface.", "Add 'extends " + SimpleBenchmark.class + "' to the class declaration.");
+ }
+ }
+
+ // TODO: should remove the caliper stack frames....
+ public static class ExceptionFromUserCodeException extends UserException {
+ public ExceptionFromUserCodeException(Throwable t) {
+ super("An exception was thrown from the benchmark code.");
+ initCause(t);
+ }
+ @Override public void display() {
+ System.err.println(error);
+ getCause().printStackTrace(System.err);
+ }
+ }
+}
diff --git a/src/com/google/caliper/Xml.java b/src/com/google/caliper/Xml.java
new file mode 100644
index 0000000..f7cfafc
--- /dev/null
+++ b/src/com/google/caliper/Xml.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.caliper;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+public final class Xml {
+ private static final String DATE_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssz";
+
+ /**
+ * Encodes this result as XML to the specified stream. This XML can be parsed
+ * with {@link #runFromXml(InputStream)}. Sample output:
+ * <pre>{@code
+ * <result benchmark="examples.FooBenchmark"
+ * executedBy="A0:1F:CAFE:BABE"
+ * executedTimestamp="2010-01-05T11:08:15PST">
+ * <scenario bar="15" foo="A" vm="dalvikvm">1200.1</scenario>
+ * <scenario bar="15" foo="B" vm="dalvikvm">1100.2</scenario>
+ * </result>
+ * }</pre>
+ */
+ public static void runToXml(Run run, OutputStream out) {
+ // BEGIN android-removed
+ // we don't have DOM level 3 on Android yet
+ // try {
+ // Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ // Element result = doc.createElement("result");
+ // doc.appendChild(result);
+ //
+ // result.setAttribute("benchmark", run.getBenchmarkName());
+ // result.setAttribute("executedBy", run.getExecutedByUuid());
+ // String executedTimestampString = new SimpleDateFormat(DATE_FORMAT_STRING)
+ // .format(run.getExecutedTimestamp());
+ // result.setAttribute("executedTimestamp", executedTimestampString);
+ //
+ // for (Map.Entry<Scenario, Double> entry : run.getMeasurements().entrySet()) {
+ // Element runElement = doc.createElement("scenario");
+ // result.appendChild(runElement);
+ //
+ // Scenario scenario = entry.getKey();
+ // for (Map.Entry<String, String> parameter : scenario.getVariables().entrySet()) {
+ // runElement.setAttribute(parameter.getKey(), parameter.getValue());
+ // }
+ // runElement.setTextContent(String.valueOf(entry.getValue()));
+ // }
+ //
+ // TransformerFactory.newInstance().newTransformer()
+ // .transform(new DOMSource(doc), new StreamResult(out));
+ // } catch (Exception e) {
+ // throw new IllegalStateException("Malformed XML document", e);
+ // }
+ // END android-removed
+ }
+
+ /**
+ * Creates a result by decoding XML from the specified stream. The XML should
+ * be consistent with the format emitted by {@link #runToXml(Run, OutputStream)}.
+ */
+ public static Run runFromXml(InputStream in) {
+ // BEGIN android-removed
+ // we don't have DOM level 3 on Android yet
+ throw new UnsupportedOperationException();
+ // try {
+ // Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);
+ // Element result = document.getDocumentElement();
+ //
+ // String benchmarkName = result.getAttribute("benchmark");
+ // String executedByUuid = result.getAttribute("executedBy");
+ // String executedDateString = result.getAttribute("executedTimestamp");
+ // Date executedDate = new SimpleDateFormat(DATE_FORMAT_STRING).parse(executedDateString);
+ //
+ // ImmutableMap.Builder<Scenario, Double> measurementsBuilder = ImmutableMap.builder();
+ // for (Node node : childrenOf(result)) {
+ // Element scenarioElement = (Element) node;
+ // Scenario scenario = new Scenario(attributesOf(scenarioElement));
+ // double measurement = Double.parseDouble(scenarioElement.getTextContent());
+ // measurementsBuilder.put(scenario, measurement);
+ // }
+ //
+ // return new Run(measurementsBuilder.build(), benchmarkName, executedByUuid, executedDate);
+ // } catch (Exception e) {
+ // throw new IllegalStateException("Malformed XML document", e);
+ // }
+ // END android-removed
+ }
+
+ private Xml() {}
+}
diff --git a/test/com/google/caliper/examples/ArraySortBenchmark.java b/src/examples/ArraySortBenchmark.java
similarity index 83%
rename from test/com/google/caliper/examples/ArraySortBenchmark.java
rename to src/examples/ArraySortBenchmark.java
index 2978fa2..f42390f 100644
--- a/test/com/google/caliper/examples/ArraySortBenchmark.java
+++ b/src/examples/ArraySortBenchmark.java
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
-
import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
import java.util.Random;
/**
@@ -30,33 +27,26 @@
*/
public class ArraySortBenchmark extends SimpleBenchmark {
- @Param int length;
+ @Param({"10", "100", "1000", "10000"}) private int length;
- static Collection<Integer> lengthValues = Arrays.asList(10, 100, 1000, 10000);
+ @Param private Distribution distribution;
- @Param Distribution distribution;
-
- static final Collection<Distribution> distributionValues = EnumSet.allOf(Distribution.class);
-
- int[] values;
- int[] copy;
+ private int[] values;
+ private int[] copy;
@Override protected void setUp() throws Exception {
values = distribution.create(length);
copy = new int[length];
}
- public int timeSort(int reps) {
- int dummy = 0;
+ public void timeSort(int reps) {
for (int i = 0; i < reps; i++) {
System.arraycopy(values, 0, copy, 0, values.length);
Arrays.sort(copy);
- dummy ^= copy[0];
}
- return dummy;
}
- enum Distribution {
+ public enum Distribution {
SAWTOOTH {
@Override
int[] create(int length) {
diff --git a/test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java b/src/examples/BoxedDoubleToStringBenchmark.java
similarity index 86%
rename from test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java
rename to src/examples/BoxedDoubleToStringBenchmark.java
index 5e6cbfa..22cb28e 100644
--- a/test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java
+++ b/src/examples/BoxedDoubleToStringBenchmark.java
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
-import com.google.caliper.SimpleBenchmark;
import com.google.caliper.Param;
import com.google.caliper.Runner;
-
-import java.util.Arrays;
+import com.google.caliper.SimpleBenchmark;
+import com.google.common.collect.ImmutableList;
import java.util.Collection;
/**
@@ -30,7 +29,9 @@
@Param private Double d;
- private static final Collection<Double> dValues = Arrays.asList(
+ // Expressing these as strings in the annotation parameter would be annoying
+ // (and maybe not possible?)
+ public static final Collection<Double> dValues = ImmutableList.of(
Math.PI,
-0.0d,
Double.NEGATIVE_INFINITY,
@@ -68,7 +69,7 @@
Double value = d;
int dummy = 0;
for (int i = 0; i < reps; i++) {
- dummy = ("" + value).length();
+ dummy += ("" + value).length();
}
return dummy;
}
diff --git a/src/examples/CharacterBenchmark.java b/src/examples/CharacterBenchmark.java
new file mode 100644
index 0000000..1e013af
--- /dev/null
+++ b/src/examples/CharacterBenchmark.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package examples;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Tests various Character methods, intended for testing multiple
+ * implementations against each other.
+ */
+public class CharacterBenchmark extends SimpleBenchmark {
+
+ @Param private CharacterSet characterSet;
+
+ @Param private Overload overload;
+
+ private char[] chars;
+
+ @Override protected void setUp() throws Exception {
+ this.chars = characterSet.chars;
+ }
+
+ public enum Overload { CHAR, INT }
+
+ public enum CharacterSet {
+ ASCII(128),
+ UNICODE(65536);
+ final char[] chars;
+ CharacterSet(int size) {
+ this.chars = new char[65536];
+ for (int i = 0; i < 65536; ++i) {
+ chars[i] = (char) (i % size);
+ }
+ }
+ }
+
+ // A fake benchmark to give us a baseline.
+ public boolean timeIsSpace(int reps) {
+ boolean dummy = false;
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ dummy ^= ((char) ch == ' ');
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ dummy ^= (ch == ' ');
+ }
+ }
+ }
+ return dummy;
+ }
+
+ public void timeDigit(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.digit(chars[ch], 10);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.digit((int) chars[ch], 10);
+ }
+ }
+ }
+ }
+
+ public void timeGetNumericValue(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.getNumericValue(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.getNumericValue((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsDigit(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isDigit(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isDigit((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsIdentifierIgnorable(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isIdentifierIgnorable(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isIdentifierIgnorable((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsJavaIdentifierPart(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierPart(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierPart((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsJavaIdentifierStart(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierStart(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierStart((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsLetter(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetter(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetter((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsLetterOrDigit(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetterOrDigit(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetterOrDigit((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsLowerCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLowerCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLowerCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsSpaceChar(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isSpaceChar(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isSpaceChar((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsUpperCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isUpperCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isUpperCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsWhitespace(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isWhitespace(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isWhitespace((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeToLowerCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toLowerCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toLowerCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeToUpperCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toUpperCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toUpperCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ // TODO: remove this from all examples when IDE plugins are ready
+ public static void main(String[] args) throws Exception {
+ Runner.main(CharacterBenchmark.class, args);
+ }
+}
diff --git a/test/com/google/caliper/examples/EnumSetContainsBenchmark.java b/src/examples/EnumSetContainsBenchmark.java
similarity index 86%
rename from test/com/google/caliper/examples/EnumSetContainsBenchmark.java
rename to src/examples/EnumSetContainsBenchmark.java
index a9f6f2f..b232514 100644
--- a/test/com/google/caliper/examples/EnumSetContainsBenchmark.java
+++ b/src/examples/EnumSetContainsBenchmark.java
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
-
-import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;
@@ -31,9 +29,7 @@
@Param private SetMaker setMaker;
- private static final Collection<SetMaker> setMakerValues = EnumSet.allOf(SetMaker.class);
-
- enum SetMaker {
+ public enum SetMaker {
ENUM_SET {
@Override Set<?> newSet() {
return EnumSet.allOf(RegularSize.class);
@@ -57,13 +53,13 @@
abstract Object[] testValues();
}
- enum RegularSize {
+ private enum RegularSize {
E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17,
E18, E19, E20, E21, E22, E23, E24, E25, E26, E27, E28, E29, E30, E31, E32,
E33, E34, E35, E36, E37, E38, E39, E40,
}
- enum LargeSize {
+ private enum LargeSize {
E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17,
E18, E19, E20, E21, E22, E23, E24, E25, E26, E27, E28, E29, E30, E31, E32,
E33, E34, E35, E36, E37, E38, E39, E40, E41, E42, E43, E44, E45, E46, E47,
@@ -79,20 +75,18 @@
private Set<?> set;
private Object[] testValues;
- @Override protected void setUp() throws Exception {
+ @Override protected void setUp() {
this.set = setMaker.newSet();
this.testValues = setMaker.testValues();
}
- public int timeContains(int reps) throws Exception {
- int dummy = 0;
+ public void timeContains(int reps) {
for (int i = 0; i < reps; i++) {
- dummy ^= (set.contains(testValues[i % testValues.length]) ? i : 0);
+ set.contains(testValues[i % testValues.length]);
}
- return dummy;
}
public static void main(String[] args) throws Exception {
Runner.main(EnumSetContainsBenchmark.class, args);
}
-}
\ No newline at end of file
+}
diff --git a/test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java b/src/examples/ExpensiveObjectsBenchmark.java
similarity index 87%
rename from test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java
rename to src/examples/ExpensiveObjectsBenchmark.java
index 2dbcf58..ebff8e6 100644
--- a/test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java
+++ b/src/examples/ExpensiveObjectsBenchmark.java
@@ -14,13 +14,10 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
-import com.google.caliper.Benchmark;
-import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
-
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
@@ -29,6 +26,7 @@
/**
* Benchmarks creation and cloning various expensive objects.
*/
+@SuppressWarnings({"ResultOfObjectAllocationIgnored"}) // TODO: should fix!
public class ExpensiveObjectsBenchmark extends SimpleBenchmark {
public void timeNewDecimalFormatSymbols(int reps) {
for (int i = 0; i < reps; ++i) {
@@ -68,4 +66,9 @@
sdf.clone();
}
}
+
+ // TODO: remove this from all examples when IDE plugins are ready
+ public static void main(String[] args) throws Exception {
+ Runner.main(ExpensiveObjectsBenchmark.class, args);
+ }
}
diff --git a/test/com/google/caliper/examples/FormatterBenchmark.java b/src/examples/FormatterBenchmark.java
similarity index 98%
rename from test/com/google/caliper/examples/FormatterBenchmark.java
rename to src/examples/FormatterBenchmark.java
index f61f111..b4a0541 100644
--- a/test/com/google/caliper/examples/FormatterBenchmark.java
+++ b/src/examples/FormatterBenchmark.java
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
-
import java.util.Formatter;
/**
diff --git a/test/com/google/caliper/examples/IntModBenchmark.java b/src/examples/IntModBenchmark.java
similarity index 82%
rename from test/com/google/caliper/examples/IntModBenchmark.java
rename to src/examples/IntModBenchmark.java
index 86e85e7..55a119c 100644
--- a/test/com/google/caliper/examples/IntModBenchmark.java
+++ b/src/examples/IntModBenchmark.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
@@ -22,6 +22,7 @@
/**
* Measures several candidate implementations for mod().
*/
+@SuppressWarnings("SameParameterValue")
public class IntModBenchmark extends SimpleBenchmark {
private static final int M = (1 << 16) - 1;
@@ -46,8 +47,9 @@
return dummy;
}
+ @SuppressWarnings("NumericCastThatLosesPrecision") // result of % by an int must be in int range
private static int doubleRemainderMod(int a, int m) {
- return (int) (((a % m) + (long) m) % m);
+ return (int) ((a % m + (long) m) % m);
}
public int timeRightShiftingMod(int reps) {
@@ -58,9 +60,10 @@
return dummy;
}
+ @SuppressWarnings("NumericCastThatLosesPrecision") // must be in int range
private static int rightShiftingMod(int a, int m) {
long r = a % m;
- return (int) (r + ((r >> 63) & m));
+ return (int) (r + (r >> 63 & m));
}
public int timeLeftShiftingMod(int reps) {
@@ -71,8 +74,9 @@
return dummy;
}
+ @SuppressWarnings("NumericCastThatLosesPrecision") // result of % by an int must be in int range
private static int leftShiftingMod(int a, int m) {
- return (int) ((a + (((long) m) << 32)) % m);
+ return (int) ((a + ((long) m << 32)) % m);
}
public int timeWrongMod(int reps) {
diff --git a/test/com/google/caliper/examples/ListIterationBenchmark.java b/src/examples/ListIterationBenchmark.java
similarity index 75%
rename from test/com/google/caliper/examples/ListIterationBenchmark.java
rename to src/examples/ListIterationBenchmark.java
index 53bcdf8..a8cfb05 100644
--- a/test/com/google/caliper/examples/ListIterationBenchmark.java
+++ b/src/examples/ListIterationBenchmark.java
@@ -14,24 +14,21 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
-
import java.util.AbstractList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
/**
* Measures iterating through list elements.
*/
public class ListIterationBenchmark extends SimpleBenchmark {
- @Param private int length;
- private static final Collection<Integer> lengthValues = Arrays.asList(0, 10, 100, 1000);
+ @Param({"0", "10", "100", "1000"})
+ private int length;
private List<Object> list;
private Object[] array;
@@ -53,24 +50,20 @@
};
}
- public int timeListIteration(int reps) {
- int count = 0;
+ @SuppressWarnings({"UnusedDeclaration"}) // TODO: fix
+ public void timeListIteration(int reps) {
for (int i = 0; i < reps; i++) {
for (Object value : list) {
- count ^= value.hashCode(); // prevent overoptimization
}
}
- return count; // ignored
}
- public int timeArrayIteration(int reps) {
- int count = 0;
+ @SuppressWarnings({"UnusedDeclaration"}) // TODO: fix
+ public void timeArrayIteration(int reps) {
for (int i = 0; i < reps; i++) {
for (Object value : array) {
- count ^= value.hashCode(); // prevent overoptimization
}
}
- return count; // ignored
}
// TODO: remove this from all examples when IDE plugins are ready
diff --git a/src/examples/LoopingBackwardsBenchmark.java b/src/examples/LoopingBackwardsBenchmark.java
new file mode 100644
index 0000000..e98e5fc
--- /dev/null
+++ b/src/examples/LoopingBackwardsBenchmark.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package examples;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Testing the old canard that looping backwards is faster.
+ *
+ * @author Kevin Bourrillion
+ */
+public class LoopingBackwardsBenchmark extends SimpleBenchmark {
+ @Param({"2", "20", "2000", "20000000"}) int max;
+
+ public int timeForwards(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ for (int j = 0; j < max; j++) {
+ dummy += j;
+ }
+ }
+ return dummy;
+ }
+
+ public int timeBackwards(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ for (int j = max - 1; j >= 0; j--) {
+ dummy += j;
+ }
+ }
+ return dummy;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Runner.main(LoopingBackwardsBenchmark.class, args);
+ }
+}
diff --git a/test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java b/src/examples/PrimitiveDoubleToStringBenchmark.java
similarity index 93%
rename from test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java
rename to src/examples/PrimitiveDoubleToStringBenchmark.java
index 592acdc..d49a53d 100644
--- a/test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java
+++ b/src/examples/PrimitiveDoubleToStringBenchmark.java
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
-import com.google.caliper.SimpleBenchmark;
import com.google.caliper.Param;
import com.google.caliper.Runner;
-
-import java.util.Arrays;
+import com.google.caliper.SimpleBenchmark;
+import com.google.common.collect.ImmutableList;
import java.util.Collection;
/**
@@ -30,7 +29,7 @@
@Param private double d;
- private static final Collection<Double> dValues = Arrays.asList(
+ public static final Collection<Double> dValues = ImmutableList.of(
Math.PI,
-0.0d,
Double.NEGATIVE_INFINITY,
diff --git a/src/examples/SetContainsBenchmark.java b/src/examples/SetContainsBenchmark.java
new file mode 100644
index 0000000..4185d55
--- /dev/null
+++ b/src/examples/SetContainsBenchmark.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package examples;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import com.google.common.collect.ImmutableSet;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * A microbenchmark that tests the performance of contains() on various Set
+ * implementations.
+ *
+ * @author Kevin Bourrillion
+ */
+public class SetContainsBenchmark extends SimpleBenchmark {
+ @Param private Impl impl;
+
+ // So far, this is the best way to test various implementations
+ public enum Impl {
+ Hash {
+ @Override Set<Integer> create(Collection<Integer> contents) {
+ return new HashSet<Integer>(contents);
+ }
+ },
+ LinkedHash {
+ @Override Set<Integer> create(Collection<Integer> contents) {
+ return new LinkedHashSet<Integer>(contents);
+ }
+ },
+ UnmodHS {
+ @Override Set<Integer> create(Collection<Integer> contents) {
+ return Collections.unmodifiableSet(new HashSet<Integer>(contents));
+ }
+ },
+ SyncHS {
+ @Override Set<Integer> create(Collection<Integer> contents) {
+ return Collections.synchronizedSet(new HashSet<Integer>(contents));
+ }
+ },
+
+ // Kind of cheating here -- Caliper just happens to bundle Google Collections so I'm testing
+ // this from it; this might not work at the command line since GC are jarjar'd for caliper.jar
+ Immutable {
+ @Override Set<Integer> create(Collection<Integer> contents) {
+ return ImmutableSet.copyOf(contents);
+ }
+ };
+
+ abstract Set<Integer> create(Collection<Integer> contents);
+ }
+
+ @Param private int size;
+ public static final Collection<Integer> sizeValues = Arrays.asList(
+ (1<<2) - 1,
+ (1<<2),
+ (1<<6) - 1,
+ (1<<6),
+ (1<<10) - 1,
+ (1<<10),
+ (1<<14) - 1,
+ (1<<14),
+ (1<<18) - 1,
+ (1<<18)
+ );
+
+ // "" means no fixed seed
+ @Param("") private SpecialRandom random;
+
+ // the following must be set during setUp
+ private Integer[] queries;
+ private Set<Integer> setToTest;
+
+ // Queries are just sequential integers. Since the contents of the set were
+ // chosen randomly, this shouldn't cause any undue bias.
+ @Override public void setUp() {
+ this.queries = new Integer[size * 2];
+ for (int i = 0; i < size * 2; i++) {
+ queries[i] = i;
+ }
+ Collections.shuffle(Arrays.asList(queries), random);
+
+ setToTest = impl.create(createData());
+ }
+
+ private Collection<Integer> createData() {
+ Set<Integer> tempSet = new HashSet<Integer>(size * 3 / 2);
+
+ // Choose 50% of the numbers between 0 and max to be in the set; thus we
+ // are measuring performance of contains() when there is a 50% hit rate
+ int max = size * 2;
+ while (tempSet.size() < size) {
+ tempSet.add(random.nextInt(max));
+ }
+ return tempSet;
+ }
+
+ public boolean timeContains(int reps) {
+ // Paranoia: acting on hearsay that accessing fields might be slow
+ // Should write a benchmark to test that!
+ Set<Integer> set = setToTest;
+ Integer[] queries = this.queries;
+
+ // Allows us to use & instead of %, acting on hearsay that division operators (/%) are
+ // disproportionately expensive; should test this too!
+ int mask = Integer.highestOneBit(size * 2) - 1;
+
+ boolean dummy = false;
+ for (int i = 0; i < reps; i++) {
+ dummy ^= set.contains(queries[i & mask]);
+ }
+ return dummy;
+ }
+
+ // TODO: remove this from all examples when IDE plugins are ready
+ public static void main(String[] args) throws Exception {
+ Runner.main(SetContainsBenchmark.class, args);
+ }
+
+
+ // Just an experiment with a slightly nicer way to create Randoms for benchies
+
+ public static class SpecialRandom extends Random {
+ public static SpecialRandom valueOf(String s) {
+ return (s.length() == 0)
+ ? new SpecialRandom()
+ : new SpecialRandom(Long.parseLong(s));
+ }
+
+ private final boolean hasSeed;
+ private final long seed;
+
+ public SpecialRandom() {
+ this.hasSeed = false;
+ this.seed = 0;
+ }
+
+ public SpecialRandom(long seed) {
+ super(seed);
+ this.hasSeed = true;
+ this.seed = seed;
+ }
+
+ @Override public String toString() {
+ return hasSeed ? "(seed:" + seed : "(default seed)";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+}
diff --git a/test/com/google/caliper/examples/StringBuilderBenchmark.java b/src/examples/StringBuilderBenchmark.java
similarity index 92%
rename from test/com/google/caliper/examples/StringBuilderBenchmark.java
rename to src/examples/StringBuilderBenchmark.java
index 2fa6819..35e34f7 100644
--- a/test/com/google/caliper/examples/StringBuilderBenchmark.java
+++ b/src/examples/StringBuilderBenchmark.java
@@ -14,23 +14,18 @@
* limitations under the License.
*/
-package com.google.caliper.examples;
+package examples;
-import com.google.caliper.Benchmark;
import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
-import java.util.Arrays;
-import java.util.Collection;
-
/**
* Tests the performance of various StringBuilder methods.
*/
public class StringBuilderBenchmark extends SimpleBenchmark {
- @Param int length;
- static Collection<Integer> lengthValues = Arrays.asList(1, 10, 100);
+ @Param({"1", "10", "100"}) private int length;
public void timeAppendBoolean(int reps) {
for (int i = 0; i < reps; ++i) {
@@ -129,4 +124,10 @@
}
}
}
+
+
+ // TODO: remove this from all examples when IDE plugins are ready
+ public static void main(String[] args) throws Exception {
+ Runner.main(StringBuilderBenchmark.class, args);
+ }
}
diff --git a/src/scripts/caliper b/src/scripts/caliper
new file mode 100644
index 0000000..fb859a9
--- /dev/null
+++ b/src/scripts/caliper
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# rough
+
+export PATH=$PATH:$JAVA_HOME/bin
+base=`dirname $0`
+exec java -cp $base/lib/caliper-@VERSION@.jar:$CLASSPATH com.google.caliper.Runner $*
+
diff --git a/src/com/google/caliper/ExecutionException.java b/src/test/BrokenNoOpBenchmark.java
similarity index 60%
rename from src/com/google/caliper/ExecutionException.java
rename to src/test/BrokenNoOpBenchmark.java
index 7d8a592..95509fa 100644
--- a/src/com/google/caliper/ExecutionException.java
+++ b/src/test/BrokenNoOpBenchmark.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,15 +14,21 @@
* limitations under the License.
*/
-package com.google.caliper;
+package test;
+
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
/**
- * Thrown upon occurrence of a runtime failure during test construction or
- * execution.
+ * This fails with a runtime out of range error.
*/
-public final class ExecutionException extends RuntimeException {
+public class BrokenNoOpBenchmark extends SimpleBenchmark {
- public ExecutionException(Throwable throwable) {
- super(throwable);
+ public void timeNoOp(int reps) {
+ for (int i = 0; i < reps; i++) {}
+ }
+
+ public static void main(String[] args) throws Exception {
+ Runner.main(BrokenNoOpBenchmark.class, args);
}
}
diff --git a/src/test/BrokenSleepBenchmark.java b/src/test/BrokenSleepBenchmark.java
new file mode 100644
index 0000000..964cf1a
--- /dev/null
+++ b/src/test/BrokenSleepBenchmark.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package test;
+
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Should fail with a measurement error.
+ */
+public class BrokenSleepBenchmark extends SimpleBenchmark {
+ // And look, IDEA tries to warn you
+ @SuppressWarnings({"UnusedDeclaration", "UnusedParameters"})
+ public void timeSleepOneSecond(int reps) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignored) {
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Runner.main(BrokenSleepBenchmark.class, args);
+ }
+}
diff --git a/src/test/ErrorsInUserCodeTest.java b/src/test/ErrorsInUserCodeTest.java
new file mode 100644
index 0000000..dbb9f88
--- /dev/null
+++ b/src/test/ErrorsInUserCodeTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package test;
+
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.UserException.AbstractBenchmarkException;
+import com.google.caliper.UserException.DoesntImplementBenchmarkException;
+import com.google.caliper.UserException.ExceptionFromUserCodeException;
+import com.google.caliper.UserException.NoParameterlessConstructorException;
+import junit.framework.TestCase;
+
+/**
+ * Unit test covering common user mistakes.
+ *
+ * @author Kevin Bourrillion
+ */
+public class ErrorsInUserCodeTest extends TestCase {
+ private Runner runner;
+
+ @Override protected void setUp() throws Exception {
+ runner = new Runner();
+ }
+
+ public void testDidntSubclassAnything() {
+ try {
+ runner.run(NotABenchmark.class.getName());
+ fail();
+ } catch (DoesntImplementBenchmarkException expected) {
+ }
+ }
+
+ static class NotABenchmark {
+ public void timeSomething(int reps) {
+ fail("" + reps);
+ }
+ }
+
+
+ public void testAbstract() {
+ try {
+ runner.run(AbstractBenchmark.class.getName());
+ fail();
+ } catch (AbstractBenchmarkException expected) {
+ }
+ }
+
+ abstract static class AbstractBenchmark extends SimpleBenchmark {
+ public void timeSomething(int reps) {
+ fail("" + reps);
+ }
+ }
+
+
+ public void testNoSuitableConstructor() {
+ try {
+ runner.run(BadConstructorBenchmark.class.getName());
+ fail();
+ } catch (NoParameterlessConstructorException expected) {
+ }
+ }
+
+ static class BadConstructorBenchmark extends SimpleBenchmark {
+ BadConstructorBenchmark(String damnParam) {
+ fail(damnParam);
+ }
+
+ public void timeSomething(int reps) {
+ fail("" + reps);
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ static class SomeUserException extends RuntimeException {}
+
+ private static void throwSomeUserException() {
+ throw new SomeUserException();
+ }
+
+
+ public void testExceptionInInit() {
+ try {
+ runner.run(ExceptionInInitBenchmark.class.getName());
+ fail();
+ } catch (ExceptionFromUserCodeException expected) {
+ }
+ }
+
+ static class ExceptionInInitBenchmark extends SimpleBenchmark {
+ static {
+ throwSomeUserException();
+ }
+
+ public void timeSomething(int reps) {
+ fail("" + reps);
+ }
+ }
+
+ public void testExceptionInConstructor() {
+ try {
+ runner.run(ExceptionInConstructorBenchmark.class.getName());
+ fail();
+ } catch (ExceptionFromUserCodeException expected) {
+ }
+ }
+
+ static class ExceptionInConstructorBenchmark extends SimpleBenchmark {
+ ExceptionInConstructorBenchmark() {
+ throw new SomeUserException();
+ }
+
+ public void timeSomething(int reps) {
+ fail("" + reps);
+ }
+ }
+
+ // TODO: enable
+ public void XXXtestExceptionInMethod() {
+ try {
+ new Runner().run(ExceptionInMethodBenchmark.class.getName());
+ fail();
+ } catch (ExceptionFromUserCodeException ignored) {
+ }
+ }
+
+ static class ExceptionInMethodBenchmark extends SimpleBenchmark {
+ public void timeSomething(int reps) {
+ throw new SomeUserException();
+ }
+ }
+}
diff --git a/src/test/RunXmlTest.java b/src/test/RunXmlTest.java
new file mode 100644
index 0000000..6dd2b63
--- /dev/null
+++ b/src/test/RunXmlTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package test;
+
+import com.google.caliper.Run;
+import com.google.caliper.Scenario;
+import com.google.caliper.Xml;
+import com.google.common.collect.ImmutableMap;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Date;
+import junit.framework.TestCase;
+
+public class RunXmlTest extends TestCase {
+
+ public void testXmlRoundtrip() {
+ Scenario a15dalvik = new Scenario(ImmutableMap.of(
+ "foo", "A", "bar", "15", "vm", "dalvikvm"));
+ Scenario b15dalvik = new Scenario(ImmutableMap.of(
+ "foo", "B", "bar", "15", "vm", "dalvikvm"));
+
+ Run toEncode = new Run(ImmutableMap.of(a15dalvik, 1200.1, b15dalvik, 1100.2),
+ "examples.FooBenchmark", "A0:1F:CAFE:BABE", new Date());
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ Xml.runToXml(toEncode, bytesOut);
+
+ assertEquals("", new String(bytesOut.toByteArray()));
+
+ // we don't validate the XML directly because it's a hassle to cope with arbitrary orderings of
+ // an element's attributes
+
+ ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray());
+ Run decoded = Xml.runFromXml(bytesIn);
+
+ assertEquals(toEncode, decoded);
+ }
+}
diff --git a/src/test/SystemOutAndErrBenchmark.java b/src/test/SystemOutAndErrBenchmark.java
new file mode 100644
index 0000000..df37d76
--- /dev/null
+++ b/src/test/SystemOutAndErrBenchmark.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package test;
+
+import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.Runner;
+
+/**
+ * Demonstrates that the benchmark can emit output without consequence.
+ */
+public class SystemOutAndErrBenchmark extends SimpleBenchmark {
+
+ public void timeSystemOutAndSystemErr(int reps) {
+ for (int i = 0; i < reps; i++) {
+ System.out.println("hello, out");
+ System.err.println("hello, err");
+ }
+ }
+
+ public static void main(String[] args) {
+ Runner.main(SystemOutAndErrBenchmark.class, args);
+ }
+}
diff --git a/src/test/ThreadSleepBenchmark.java b/src/test/ThreadSleepBenchmark.java
new file mode 100644
index 0000000..bfb6c05
--- /dev/null
+++ b/src/test/ThreadSleepBenchmark.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package test;
+
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * If everything is working properly, this should report runtime very close to
+ * 1ms.
+ */
+public class ThreadSleepBenchmark extends SimpleBenchmark {
+
+ public void timeSleep(int reps) {
+ try {
+ Thread.sleep(reps);
+ } catch (InterruptedException ignored) {
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Runner.main(ThreadSleepBenchmark.class, args);
+ }
+}
diff --git a/src/test/TracingBenchmark.java b/src/test/TracingBenchmark.java
new file mode 100644
index 0000000..2f1c077
--- /dev/null
+++ b/src/test/TracingBenchmark.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package test;
+
+import com.google.caliper.Benchmark;
+import com.google.caliper.TimedRunnable;
+import com.google.caliper.Runner;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * Proof-of-concept of a decorating benchmark.
+ */
+public class TracingBenchmark implements Benchmark {
+
+ private final Benchmark delegate;
+
+ public TracingBenchmark() {
+ this.delegate = new ThreadSleepBenchmark();
+ }
+
+ public Set<String> parameterNames() {
+ return delegate.parameterNames();
+ }
+
+ public Set<String> parameterValues(String parameterName) {
+ return delegate.parameterValues(parameterName);
+ }
+
+ public TimedRunnable createBenchmark(Map<String, String> parameterValues) {
+ final TimedRunnable benchmark = delegate.createBenchmark(parameterValues);
+
+ return new TimedRunnable() {
+ public Object run(int reps) throws Exception {
+ // TODO: can we move the setup/tear down work out of the timed loop?
+ Runtime.getRuntime().traceMethodCalls(true);
+ try {
+ return benchmark.run(reps);
+ } finally {
+ Runtime.getRuntime().traceMethodCalls(false);
+ }
+ }
+ };
+ }
+
+ public static void main(String[] args) {
+ Runner.main(TracingBenchmark.class);
+ }
+}
diff --git a/src/tutorial/Tutorial.java b/src/tutorial/Tutorial.java
new file mode 100644
index 0000000..06e6e56
--- /dev/null
+++ b/src/tutorial/Tutorial.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tutorial;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Caliper tutorial. To run the example benchmarks in this file:
+ * {@code CLASSPATH=... [caliper_home]/caliper tutorial.Tutorial.Benchmark1}
+ *
+ * @author Kevin Bourrillion
+ */
+public class Tutorial {
+
+ /*
+ * We begin the Caliper tutorial with the simplest benchmark you can write.
+ * We'd like to know how efficient the method System.nanoTime() is.
+ *
+ * Notice:
+ *
+ * - We write a class that extends com.google.caliper.SimpleBenchmark.
+ * - It contains a public instance method whose name begins with 'time' and
+ * and which accepts a single 'int reps' parameter.
+ * - The body of the method simply executes the code we wish to measure,
+ * 'reps' times.
+ *
+ * Example run:
+ *
+ * $ CLASSPATH=build/classes/test caliper tutorial.Tutorial.Benchmark1
+ * [real-time results appear on this line]
+ *
+ * Summary report for tutorial.Tutorial$Benchmark1:
+ *
+ * Benchmark ns
+ * --------- ---
+ * NanoTime 233
+ */
+ public static class Benchmark1 extends SimpleBenchmark {
+ public void timeNanoTime(int reps) {
+ for (int i = 0; i < reps; i++) {
+ System.nanoTime();
+ }
+ }
+ }
+
+ /*
+ * Now let's compare two things: nanoTime() versus currentTimeMillis().
+ * Notice:
+ *
+ * - We simply add another method, following the same rules as the first.
+ *
+ * Example run output:
+ *
+ * Benchmark ns
+ * ----------------- ---
+ * NanoTime 248
+ * CurrentTimeMillis 118
+ */
+ public static class Benchmark2 extends SimpleBenchmark {
+ public void timeNanoTime(int reps) {
+ for (int i = 0; i < reps; i++) {
+ System.nanoTime();
+ }
+ }
+ public void timeCurrentTimeMillis(int reps) {
+ for (int i = 0; i < reps; i++) {
+ System.currentTimeMillis();
+ }
+ }
+ }
+
+ /*
+ * Let's try iterating over a large array. This seems simple enough, but
+ * there is a problem!
+ */
+ public static class Benchmark3 extends SimpleBenchmark {
+ private final int[] array = new int[1000000];
+
+ @SuppressWarnings("UnusedDeclaration") // IDEA tries to warn us!
+ public void timeArrayIteration_BAD(int reps) {
+ for (int i = 0; i < reps; i++) {
+ for (int ignoreMe : array) {}
+ }
+ }
+ }
+
+ /*
+ * Caliper reported that the benchmark above ran in 4 nanoseconds.
+ *
+ * Wait, what?
+ *
+ * How can it possibly iterate over a million zeroes in 4 ns!?
+ *
+ * It is very important to sanity-check benchmark results with common sense!
+ * In this case, we're indeed getting a bogus result. The problem is that the
+ * Java Virtual Machine is too smart: it detected the fact that the loop was
+ * producing no actual result, so it simply compiled it right out. The method
+ * never looped at all. To fix this, we need to use a dummy result value.
+ *
+ * Notice:
+ *
+ * - We simply change the 'time' method from 'void' to any return type we
+ * wish. Then we return a value that can't be known without actually
+ * performing the work, and thus we defeat the runtime optimizations.
+ * - We're no longer timing *just* the code we want to be testing - our
+ * result will now be inflated by the (small) cost of addition. This is an
+ * unfortunate fact of life with microbenchmarking. In fact, we were
+ * already inflated by the cost of an int comparison, "i < reps" as it was.
+ *
+ * With this change, Caliper should report a much more realistic value, more
+ * on the order of an entire millisecond.
+ */
+ public static class Benchmark4 extends SimpleBenchmark {
+ private final int[] array = new int[1000000];
+
+ public int timeArrayIteration_fixed(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ for (int doNotIgnoreMe : array) {
+ dummy += doNotIgnoreMe;
+ }
+ }
+ return dummy; // framework ignores this, but it has served its purpose!
+ }
+ }
+
+ /*
+ * Now we'd like to know how various other *sizes* of arrays perform. We
+ * don't want to have to cut and paste the whole benchmark just to provide a
+ * different size. What we need is a parameter!
+ *
+ * When you run this benchmark the same way you ran the previous ones, you'll
+ * now get an error: "No values provided for benchmark parameter 'size'".
+ * You can provide the value requested at the command line like this:
+ *
+ * [caliper_home]/caliper tutorial.Tutorial.Benchmark5 -Dsize=100}
+ *
+ * You'll see output like this:
+ *
+ * Benchmark size ns
+ * -------------- ---- ---
+ * ArrayIteration 100 51
+ *
+ * Now that we've parameterized our benchmark, things are starting to get fun.
+ * Try passing '-Dsize=10,100,1000' and see what happens!
+ *
+ * Benchmark size ns
+ * -------------- ---- -----------------------------------
+ * ArrayIteration 10 7 |
+ * ArrayIteration 100 49 ||||
+ * ArrayIteration 1000 477 ||||||||||||||||||||||||||||||
+ *
+ */
+ public static class Benchmark5 extends SimpleBenchmark {
+ @Param int size; // set automatically by framework
+
+ private int[] array; // set by us, in setUp()
+
+ @Override protected void setUp() {
+ // @Param values are guaranteed to have been injected by now
+ array = new int[size];
+ }
+
+ public int timeArrayIteration(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ for (int doNotIgnoreMe : array) {
+ dummy += doNotIgnoreMe;
+ }
+ }
+ return dummy;
+ }
+ }
+}
diff --git a/test/com/google/caliper/AllTests.java b/test/com/google/caliper/AllTests.java
deleted file mode 100644
index 510cc0a..0000000
--- a/test/com/google/caliper/AllTests.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.caliper;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public final class AllTests {
- public static Test suite() {
- TestSuite suite = new TestSuite();
- // tests go here :)
- return suite;
- }
-}
diff --git a/test/com/google/caliper/examples/CharacterBenchmark.java b/test/com/google/caliper/examples/CharacterBenchmark.java
deleted file mode 100644
index 3ffeb01..0000000
--- a/test/com/google/caliper/examples/CharacterBenchmark.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.caliper.examples;
-
-import com.google.caliper.Benchmark;
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Collection;
-import java.util.EnumSet;
-
-/**
- * Tests various Character methods, intended for testing multiple
- * implementations against each other.
- */
-public class CharacterBenchmark extends SimpleBenchmark {
-
- @Param CharacterSet characterSet;
- static Collection<CharacterSet> characterSetValues = EnumSet.allOf(CharacterSet.class);
-
- char[] values;
-
- @Override protected void setUp() throws Exception {
- values = characterSet.chars;
- }
-
- enum CharacterSet {
- ASCII(128),
- UNICODE(65536);
- char[] chars;
- CharacterSet(int size) {
- chars = new char[size];
- for (int i = 0; i < chars.length; ++i) {
- chars[i] = (char) i;
- }
- }
- }
-
- public void timeDigit(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.digit(ch, 10);
- }
- }
- }
-
- public void timeGetNumericValue(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.getNumericValue(ch);
- }
- }
- }
-
- public void timeIsDigit(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isDigit(ch);
- }
- }
- }
-
- public void timeIsIdentifierIgnorable(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isIdentifierIgnorable(ch);
- }
- }
- }
-
- public void timeIsJavaIdentifierPart(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isJavaIdentifierPart(ch);
- }
- }
- }
-
- public void timeIsJavaIdentifierStart(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isJavaIdentifierStart(ch);
- }
- }
- }
-
- public void timeIsLetter(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isLetter(ch);
- }
- }
- }
-
- public void timeIsLetterOrDigit(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isLetterOrDigit(ch);
- }
- }
- }
-
- public void timeIsLowerCase(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isLowerCase(ch);
- }
- }
- }
-
- public void timeIsSpaceChar(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isSpaceChar(ch);
- }
- }
- }
-
- public void timeIsUpperCase(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isUpperCase(ch);
- }
- }
- }
-
- public void timeIsWhitespace(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.isWhitespace(ch);
- }
- }
- }
-
- public void timeIsNull(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- boolean b = (ch == ' ');
- }
- }
- }
-
- public void timeToLowerCase(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.toLowerCase(ch);
- }
- }
- }
-
- public void timeToUpperCase(int reps) {
- for (int i = 0; i < reps; ++i) {
- for (char ch = 0; ch < '}'; ++ch) {
- Character.toUpperCase(ch);
- }
- }
- }
-}