You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2018/07/15 16:18:04 UTC

[uima-uimafit] branch feature/UIMA-5823-Add-basic-benchmarking-module created (now badb72c)

This is an automated email from the ASF dual-hosted git repository.

rec pushed a change to branch feature/UIMA-5823-Add-basic-benchmarking-module
in repository https://gitbox.apache.org/repos/asf/uima-uimafit.git.


      at badb72c  [UIMA-5823] Add basic benchmarking module

This branch includes the following new commits:

     new badb72c  [UIMA-5823] Add basic benchmarking module

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[uima-uimafit] 01/01: [UIMA-5823] Add basic benchmarking module

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rec pushed a commit to branch feature/UIMA-5823-Add-basic-benchmarking-module
in repository https://gitbox.apache.org/repos/asf/uima-uimafit.git

commit badb72c4cfd0bf087f9eb48974edf13e0f1f9a60
Author: Richard Eckart de Castilho <re...@apache.org>
AuthorDate: Sun Jul 15 18:17:44 2018 +0200

    [UIMA-5823] Add basic benchmarking module
    
    - Added new benchmark module
    - Added basic benchmarking utility code
    - Added a few benchmarks of (J)CasUtil methods
---
 pom.xml                                            |   1 +
 uimafit-benchmark/pom.xml                          | 128 ++++++++++++++++++
 .../java/org/apache/uima/fit/benchmark/Batch.java  |  70 ++++++++++
 .../org/apache/uima/fit/benchmark/Benchmark.java   | 149 +++++++++++++++++++++
 .../uima/fit/benchmark/CasInitializationUtils.java |  71 ++++++++++
 .../org/apache/uima/fit/benchmark/Measurement.java |  64 +++++++++
 .../uima/fit/benchmark/RunnableWithExceptions.java |   5 +
 .../META-INF/org.apache.uima.fit/types.txt         |   1 +
 .../org/apache/uima/fit/type/Sentence.xml          |  32 +++++
 .../resources/org/apache/uima/fit/type/Token.xml   |  44 ++++++
 .../uima/fit/benchmark/CasUtilBenchmark.java       | 111 +++++++++++++++
 .../apache/uima/fit/benchmark/FSUtilBenchmark.java |  54 ++++++++
 .../uima/fit/benchmark/JCasFactoryBenchmark.java   |  60 +++++++++
 .../uima/fit/benchmark/JCasUtilBenchmark.java      | 105 +++++++++++++++
 14 files changed, 895 insertions(+)

diff --git a/pom.xml b/pom.xml
index 672cfd9..11735f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -115,6 +115,7 @@
 		<module>uimafit-legacy-support</module>
 		<module>uimafit-docbook</module>
 		<module>uimafit-cpe</module>
+    <module>uimafit-benchmark</module>
 		<module>uimafit-parent</module>
 	</modules>
 
diff --git a/uimafit-benchmark/pom.xml b/uimafit-benchmark/pom.xml
new file mode 100644
index 0000000..d39fc5e
--- /dev/null
+++ b/uimafit-benchmark/pom.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>uimafit-benchmark</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache UIMA uimaFIT - Benchmark</name>
+  <description>Factories, Injection, and Testing library for UIMA</description>
+  <url>${uimaWebsiteUrl}</url>
+  <parent>
+    <groupId>org.apache.uima</groupId>
+    <artifactId>uimafit-parent</artifactId>
+    <version>2.5.0-SNAPSHOT</version>
+    <relativePath>../uimafit-parent</relativePath>
+  </parent>
+  <properties>
+    <maven.deploy.skip>true</maven.deploy.skip>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
+      <artifactId>uimafit-core</artifactId>
+      <version>2.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-math3</artifactId>
+      <version>3.6.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <licenses>
+    <license>
+      <name>Apache License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.uima</groupId>
+        <artifactId>jcasgen-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+            <configuration>
+              <typeSystemIncludes>
+                <typeSystemInclude>src/main/resources/org/apache/uima/fit/type/**/*.xml</typeSystemInclude>
+              </typeSystemIncludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <!--
+          This plug-in adds the jcasgen generated source code folder as a project
+          source folder
+        -->
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>add-test-source</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>add-test-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>${project.build.directory}/generated-sources/jcasgen</source>
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>default-cli</id>
+              <configuration>
+                <excludes combine.children="append">
+                  <!-- These test files are unreasonable to bear a license header -->
+                  <exclude>src/test/resources/log4j.properties</exclude>
+                  <!-- These configuration files cannot bear a license header -->
+                  <exclude>src/test/resources/META-INF/org.apache.uima.fit/fsindexes.txt</exclude>
+                  <exclude>src/test/resources/META-INF/org.apache.uima.fit/typepriorities.txt</exclude>
+                  <exclude>src/test/resources/META-INF/org.apache.uima.fit/types.txt</exclude>
+                </excludes>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
\ No newline at end of file
diff --git a/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Batch.java b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Batch.java
new file mode 100644
index 0000000..a4fd351
--- /dev/null
+++ b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Batch.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+
+public class Batch {
+    private List<Measurement> measurements = new ArrayList<>();
+    
+    private final int magnitude;
+    
+    public Batch(int aMagnitude) {
+      magnitude = aMagnitude;
+    }
+    
+    public int getMagnitude() {
+      return magnitude;
+    }
+    
+    public void addMeasurement(Measurement aMeasurement) {
+      measurements.add(aMeasurement);
+    }
+    
+    public List<Measurement> getMeasurements() {
+      return measurements;
+    }
+    
+    @Override
+    public String toString()
+    {
+      DescriptiveStatistics stats = new DescriptiveStatistics();
+      
+      StringBuilder sb = new StringBuilder();
+      sb.append("[").append(String.format("%7d/%7d", magnitude, measurements.size())).append(": ");
+      int failures = 0;
+      for (Measurement m : measurements) {
+        if (m.failed()) {
+          failures++;
+        }
+        else {
+          stats.addValue(m.getDuration());
+        }
+      }
+      sb.append(String.format("min: %4.0f ", stats.getMin()));
+      sb.append(String.format("max: %4.0f ", stats.getMax()));
+      sb.append(String.format("median: %4.0f ", stats.getPercentile(50)));
+      sb.append(String.format("fail: %4d ", failures));
+      sb.append("]");
+      return sb.toString();
+    }
+  }
\ No newline at end of file
diff --git a/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Benchmark.java b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Benchmark.java
new file mode 100644
index 0000000..1b998e3
--- /dev/null
+++ b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Benchmark.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.LongSupplier;
+
+import org.apache.commons.lang.StringUtils;
+
+public class Benchmark {
+    private IntConsumer initializer = t -> {};
+    private RunnableWithExceptions subject;
+    
+    private String name;
+    private int baseRepeat = 20;
+    private int repeatIncrementTimes;
+    
+    private int baseMagnitude = 1;
+    private int incrementTimes;
+    private IntFunction<Integer> magnitudeIncrement = t -> t;
+    private LongSupplier timer = () -> System.currentTimeMillis();
+    
+    private List<Batch> batches = new ArrayList<>();
+
+    public Benchmark(String aName, Benchmark aTemplate) {
+      name = aName;
+      
+      initializer = aTemplate.initializer;
+      subject = aTemplate.subject;
+      
+      baseRepeat = aTemplate.baseRepeat;
+      repeatIncrementTimes = aTemplate.repeatIncrementTimes;
+      
+      baseMagnitude = aTemplate.baseMagnitude;
+      incrementTimes = aTemplate.incrementTimes;
+      magnitudeIncrement = aTemplate.magnitudeIncrement;
+      timer = aTemplate.timer;
+    }
+
+    public Benchmark(String aName) {
+      name = aName;
+    }
+
+    public Benchmark timer(LongSupplier aTimer)
+    {
+      timer = aTimer;
+      return this;
+    }
+
+    public Benchmark repeat(int aRepeat)
+    {
+      baseRepeat = aRepeat;
+      return this;
+    }
+
+    public Benchmark magnitude(int aMagnitude)
+    {
+      baseMagnitude = aMagnitude;
+      return this;
+    }
+
+    public Benchmark magnitudeIncrement(IntFunction<Integer> aIncrement)
+    {
+      magnitudeIncrement = aIncrement;
+      return this;
+    }
+
+    public Benchmark incrementTimes(int aTimes)
+    {
+      incrementTimes = aTimes;
+      return this;
+    }
+
+    public Benchmark initialize(IntConsumer aPieceOfCode)
+    {
+      initializer = aPieceOfCode;
+      return this;
+    }
+    
+    public Benchmark measure(RunnableWithExceptions aPieceOfCode)
+    {
+      subject = aPieceOfCode;
+      return this;
+    }
+    
+    private Batch runBatch(int aMagnitude)
+    {
+      Batch batch = new Batch(aMagnitude);
+      
+      initializer.accept(aMagnitude);
+      for (int i = 0; i < baseRepeat; i++) {
+        
+        long startTime = timer.getAsLong();
+        try {
+          subject.run();
+          batch.addMeasurement(new Measurement(i, timer.getAsLong() - startTime));
+        }
+        catch (Exception e) {
+          batch.addMeasurement(new Measurement(i, timer.getAsLong() - startTime, e));
+        }
+      }
+      
+      return batch;
+    }
+    
+    public void run()
+    {
+      System.out.printf("%n%s%n", StringUtils.repeat("=", name.length()));
+      System.out.printf("%s%n", name);
+      System.out.printf("%s%n", StringUtils.repeat("=", name.length()));
+      
+      int magnitude = baseMagnitude;
+      int n = 0;
+      
+      System.out.print("Running benchmark... ");
+      do {
+        if (magnitude > 0) {
+          System.out.printf("%d ", magnitude);
+        }
+        batches.add(runBatch(magnitude));
+        magnitude = magnitudeIncrement.apply(magnitude);
+        n++;
+      } while (n < incrementTimes);
+      System.out.printf("%n%n");
+      
+      for (Batch b : batches) {
+        System.out.printf("%s%n", b);
+      }
+    }
+  }
\ No newline at end of file
diff --git a/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/CasInitializationUtils.java b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/CasInitializationUtils.java
new file mode 100644
index 0000000..e9e53c2
--- /dev/null
+++ b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/CasInitializationUtils.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.CASException;
+import org.apache.uima.cas.Type;
+import org.apache.uima.fit.type.Sentence;
+import org.apache.uima.fit.type.Token;
+
+public final class CasInitializationUtils
+{
+    private static final long RANDOM_SEED = 12345l;
+
+    private CasInitializationUtils()
+    {
+        // No instances
+    }
+
+    public static void initRandomCas(CAS cas, int size)
+    {
+        cas.reset();
+        Random rnd = new Random(RANDOM_SEED);
+        List<Type> types = new ArrayList<Type>();
+        types.add(cas.getTypeSystem().getType(Token.class.getName()));
+        types.add(cas.getTypeSystem().getType(Sentence.class.getName()));
+
+        // Shuffle the types
+        for (int n = 0; n < 10; n++) {
+            Type t = types.remove(rnd.nextInt(types.size()));
+            types.add(t);
+        }
+
+        // Randomly generate annotations
+        for (int n = 0; n < size; n++) {
+            for (Type t : types) {
+                int begin = rnd.nextInt(100);
+                int end = begin + rnd.nextInt(30);
+                cas.addFsToIndexes(cas.createAnnotation(t, begin, end));
+            }
+        }
+
+        try {
+            cas.getJCas();
+        }
+        catch (CASException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Measurement.java b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Measurement.java
new file mode 100644
index 0000000..ace262e
--- /dev/null
+++ b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/Measurement.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+public class Measurement {
+    private final int run;
+    private final long duration;
+    private final Exception exception;
+    
+    public Measurement(int aRun, long aDuration) {
+      run = aRun;
+      duration = aDuration;
+      exception = null;
+    }
+    
+    public Measurement(int aRun, long aDuration, Exception aException) {
+      exception = aException;
+      run = aRun;
+      duration = aDuration;
+    }
+
+    public int getRun() {
+      return run;
+    }
+    
+    public long getDuration() {
+      return duration;
+    }
+    
+    public Exception getException() {
+      return exception;
+    }
+    
+    public boolean failed() {
+      return exception != null;
+    }
+    
+    @Override
+    public String toString()
+    {
+      if (failed()) {
+        return "[" + run + ": FAIL]";
+      }
+      else {
+        return "[" + run + ": " + duration + "]";
+      }
+    }
+  }
\ No newline at end of file
diff --git a/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/RunnableWithExceptions.java b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/RunnableWithExceptions.java
new file mode 100644
index 0000000..262c454
--- /dev/null
+++ b/uimafit-benchmark/src/main/java/org/apache/uima/fit/benchmark/RunnableWithExceptions.java
@@ -0,0 +1,5 @@
+package org.apache.uima.fit.benchmark;
+
+public interface RunnableWithExceptions {
+    void run() throws Exception;
+  }
\ No newline at end of file
diff --git a/uimafit-benchmark/src/main/resources/META-INF/org.apache.uima.fit/types.txt b/uimafit-benchmark/src/main/resources/META-INF/org.apache.uima.fit/types.txt
new file mode 100644
index 0000000..1c96dc9
--- /dev/null
+++ b/uimafit-benchmark/src/main/resources/META-INF/org.apache.uima.fit/types.txt
@@ -0,0 +1 @@
+classpath*:org/apache/uima/fit/type/**/*.xml
diff --git a/uimafit-benchmark/src/main/resources/org/apache/uima/fit/type/Sentence.xml b/uimafit-benchmark/src/main/resources/org/apache/uima/fit/type/Sentence.xml
new file mode 100644
index 0000000..a69681d
--- /dev/null
+++ b/uimafit-benchmark/src/main/resources/org/apache/uima/fit/type/Sentence.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements. See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership. The ASF licenses this file
+	to you 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.
+-->
+<typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">
+  <name>Sentence</name>
+  <description></description>
+  <version>1.0</version>
+  <vendor/>
+  <types>
+    <typeDescription>
+      <name>org.apache.uima.fit.type.Sentence</name>
+      <description/>
+      <supertypeName>uima.tcas.Annotation</supertypeName>
+    </typeDescription>
+  </types>
+</typeSystemDescription>
diff --git a/uimafit-benchmark/src/main/resources/org/apache/uima/fit/type/Token.xml b/uimafit-benchmark/src/main/resources/org/apache/uima/fit/type/Token.xml
new file mode 100644
index 0000000..629ae03
--- /dev/null
+++ b/uimafit-benchmark/src/main/resources/org/apache/uima/fit/type/Token.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements. See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership. The ASF licenses this file
+	to you 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.
+-->
+<typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">
+  <name>Token</name>
+  <description></description>
+  <version>1.0</version>
+  <vendor/>
+  <types>
+    <typeDescription>
+      <name>org.apache.uima.fit.type.Token</name>
+      <description/>
+      <supertypeName>uima.tcas.Annotation</supertypeName>
+      <features>
+        <featureDescription>
+          <name>pos</name>
+          <description/>
+          <rangeTypeName>uima.cas.String</rangeTypeName>
+        </featureDescription>
+        <featureDescription>
+          <name>stem</name>
+          <description/>
+          <rangeTypeName>uima.cas.String</rangeTypeName>
+        </featureDescription>
+      </features>
+    </typeDescription>
+  </types>
+</typeSystemDescription>
diff --git a/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/CasUtilBenchmark.java b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/CasUtilBenchmark.java
new file mode 100644
index 0000000..59132c8
--- /dev/null
+++ b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/CasUtilBenchmark.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import static org.apache.uima.fit.factory.TypeSystemDescriptionFactory.*;
+import static org.apache.uima.fit.benchmark.CasInitializationUtils.initRandomCas;
+import static org.apache.uima.fit.util.CasUtil.indexCovered;
+import static org.apache.uima.fit.util.CasUtil.select;
+import static org.apache.uima.fit.util.CasUtil.selectAll;
+import static org.apache.uima.fit.util.CasUtil.*;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.util.CasCreationUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CasUtilBenchmark {
+  private CAS cas;
+  
+  private static final String TYPE_NAME_TOKEN = "org.apache.uima.fit.type.Token";
+  private static final String TYPE_NAME_SENTENCE = "org.apache.uima.fit.type.Sentence";
+  
+  @Before
+  public void setup() throws Exception {
+    if (cas == null) {
+      cas = CasCreationUtils.createCas(createTypeSystemDescription(), null, null);
+    }
+    else {
+      cas.reset();
+    }
+  }
+
+  @Test
+  public void benchmarkSelect() {
+    Benchmark template = new Benchmark("TEMPLATE")
+      .initialize(n -> initRandomCas(cas, n))
+      .magnitude(10)
+      .magnitudeIncrement(count -> count * 10)
+      .incrementTimes(5);
+    
+    new Benchmark("CAS select Token", template)
+      .measure(() -> select(cas, getType(cas, TYPE_NAME_TOKEN)))
+      .run();
+
+    new Benchmark("CAS select Token and iterate", template)
+      .measure(() -> select(cas, getType(cas, TYPE_NAME_TOKEN)).forEach(v -> {}))
+      .run();
+
+    new Benchmark("CAS select Sentence", template)
+      .measure(() -> select(cas, getType(cas, TYPE_NAME_SENTENCE)))
+      .run();
+
+    new Benchmark("CAS select Sentence and iterate", template)
+      .measure(() -> select(cas, getType(cas, TYPE_NAME_SENTENCE)).forEach(v -> {}))
+      .run();
+    
+    new Benchmark("CAS select TOP", template)
+      .measure(() -> selectFS(cas, getType(cas, CAS.TYPE_NAME_TOP)))
+      .run();
+
+    new Benchmark("CAS select TOP and iterate", template)
+      .measure(() -> selectFS(cas, getType(cas, CAS.TYPE_NAME_TOP)).forEach(v -> {}))
+      .run();
+    
+    new Benchmark("CAS select ALL", template)
+      .measure(() -> selectAll(cas))
+      .run();
+    
+    new Benchmark("CAS select ALL and iterate", template)
+      .measure(() -> selectAll(cas).forEach(v -> {}))
+      .run();
+  }
+  
+  @Test
+  public void benchmarkSelectCovered() {
+    Benchmark template = new Benchmark("TEMPLATE")
+        .initialize(n -> initRandomCas(cas, n))
+        .magnitude(10)
+        .magnitudeIncrement(count -> count * 10)
+        .incrementTimes(4);
+    
+    new Benchmark("CAS selectCovered", template)
+      .measure(() -> {
+      	Type sentenceType = getType(cas, TYPE_NAME_SENTENCE);
+      	Type tokenType = getType(cas, TYPE_NAME_TOKEN);
+      	select(cas, sentenceType).forEach(s -> selectCovered(tokenType, s));
+      })
+      .run();
+
+    new Benchmark("CAS indexCovered", template)
+      .measure(() -> indexCovered(cas, getType(cas, TYPE_NAME_SENTENCE), getType(cas, TYPE_NAME_TOKEN)))
+      .run();
+  }
+}
diff --git a/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/FSUtilBenchmark.java b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/FSUtilBenchmark.java
new file mode 100644
index 0000000..536e234
--- /dev/null
+++ b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/FSUtilBenchmark.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import static org.apache.uima.fit.util.FSUtil.setFeature;
+
+import org.apache.uima.fit.factory.JCasFactory;
+import org.apache.uima.fit.type.Token;
+import org.apache.uima.jcas.JCas;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class FSUtilBenchmark {
+	private static JCas jcas;
+	private static Token fs;
+
+	@BeforeClass
+  public static void setupOnce() throws Exception {
+  	jcas = JCasFactory.createText("test");
+  	fs = new Token(jcas, 0, 1);
+  	fs.addToIndexes();
+  }
+
+	@Test
+  public void benchmarkSetFeature() {
+    Benchmark template = new Benchmark("TEMPLATE")
+      .timer(System::nanoTime)
+      .repeat(1_000_000);
+
+    new Benchmark("set feature string JCas", template)
+      .measure(() -> fs.setPos("NN"))
+      .run();
+
+    new Benchmark("set feature string", template)
+      .measure(() -> setFeature(fs, "pos", "NN"))
+      .run();
+  }
+}
diff --git a/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/JCasFactoryBenchmark.java b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/JCasFactoryBenchmark.java
new file mode 100644
index 0000000..3ca8157
--- /dev/null
+++ b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/JCasFactoryBenchmark.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import static org.apache.uima.fit.factory.TypeSystemDescriptionFactory.createTypeSystemDescription;
+
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.util.CasCreationUtils;
+import org.junit.Test;
+
+public class JCasFactoryBenchmark
+{
+  @Test
+  public void benchmarkCreateTypeSystemDescription() throws Exception {
+    Benchmark template = new Benchmark("TEMPLATE")
+      .timer(System::currentTimeMillis)
+      .repeat(1000);
+    
+    new Benchmark("createTypeSystemDescription", template)
+      .measure(() -> createTypeSystemDescription())
+      .run();
+  }
+	
+  @Test
+  public void benchmarkCreateJCas() throws Exception {
+    Benchmark template = new Benchmark("TEMPLATE")
+      .timer(System::currentTimeMillis)
+      .repeat(1000);
+    
+    TypeSystemDescription tsd = createTypeSystemDescription();
+    
+    new Benchmark("create CAS", template)
+      .measure(() -> CasCreationUtils.createCas(tsd, null, null))
+      .run();
+
+    new Benchmark("create JCas (fresh TSD)", template)
+      .measure(() -> CasCreationUtils.createCas(createTypeSystemDescription(), null, null).getJCas())
+      .run();
+    
+    new Benchmark("create JCas (re-use TSD)", template)
+      .measure(() -> CasCreationUtils.createCas(tsd, null, null).getJCas())
+      .run();
+  }
+}
diff --git a/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/JCasUtilBenchmark.java b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/JCasUtilBenchmark.java
new file mode 100644
index 0000000..d7db0d8
--- /dev/null
+++ b/uimafit-benchmark/src/test/java/org/apache/uima/fit/benchmark/JCasUtilBenchmark.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.uima.fit.benchmark;
+
+import static org.apache.uima.fit.benchmark.CasInitializationUtils.initRandomCas;
+import static org.apache.uima.fit.util.JCasUtil.indexCovered;
+import static org.apache.uima.fit.util.JCasUtil.select;
+import static org.apache.uima.fit.util.JCasUtil.selectAll;
+import static org.apache.uima.fit.util.JCasUtil.selectCovered;
+
+import org.apache.uima.fit.factory.JCasFactory;
+import org.apache.uima.fit.type.Sentence;
+import org.apache.uima.fit.type.Token;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.TOP;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JCasUtilBenchmark {
+  private JCas jcas;
+  
+  @Before
+  public void setup() throws Exception {
+    if (jcas == null) {
+      jcas = JCasFactory.createJCas();
+    }
+    else {
+      jcas.reset();
+    }
+  }
+
+  @Test
+  public void benchmarkSelect() {
+    Benchmark template = new Benchmark("TEMPLATE")
+      .initialize(n -> initRandomCas(jcas.getCas(), n))
+      .magnitude(10)
+      .magnitudeIncrement(count -> count * 10)
+      .incrementTimes(5);
+    
+    new Benchmark("JCas select Token", template)
+      .measure(() -> select(jcas, Token.class))
+      .run();
+
+    new Benchmark("JCas select Token and iterate", template)
+      .measure(() -> select(jcas, Token.class).forEach(v -> {}))
+      .run();
+
+    new Benchmark("JCas select Sentence", template)
+      .measure(() -> select(jcas, Sentence.class))
+      .run();
+
+    new Benchmark("JCas select Sentence and iterate", template)
+      .measure(() -> select(jcas, Sentence.class).forEach(v -> {}))
+      .run();
+    
+    new Benchmark("JCas select TOP", template)
+      .measure(() -> select(jcas, TOP.class))
+      .run();
+
+    new Benchmark("JCas select TOP and iterate", template)
+      .measure(() -> select(jcas, TOP.class).forEach(v -> {}))
+      .run();
+    
+    new Benchmark("JCas select ALL", template)
+      .measure(() -> selectAll(jcas))
+      .run();
+    
+    new Benchmark("JCas select ALL and iterate", template)
+      .measure(() -> selectAll(jcas).forEach(v -> {}))
+      .run();
+  }
+  
+  @Test
+  public void benchmarkSelectCovered() {
+    Benchmark template = new Benchmark("TEMPLATE")
+        .initialize(n -> initRandomCas(jcas.getCas(), n))
+        .magnitude(10)
+        .magnitudeIncrement(count -> count * 10)
+        .incrementTimes(4);
+    
+    new Benchmark("JCas selectCovered", template)
+      .measure(() -> select(jcas, Sentence.class).forEach(s -> selectCovered(Token.class, s)))
+      .run();
+
+    new Benchmark("JCas indexCovered", template)
+      .measure(() -> indexCovered(jcas, Sentence.class, Token.class))
+      .run();
+  }
+}