Created
          December 17, 2019 11:44 
        
      - 
      
- 
        Save rzwitserloot/ecc249e8391d0699ca6a4c6904ddd585 to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | create via: | |
| mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -DgroupId=com.zwitserloot -DartifactId=boyermoore -Dversion=1.0 | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package com.zwitserloot; | |
| import org.openjdk.jmh.annotations.*; | |
| import java.nio.charset.*; | |
| import java.util.Arrays; | |
| public class MyBenchmark { | |
| private static final int HAYSTACK_SIZE = 100; | |
| public static void main(String[] args) { | |
| MyState s = new MyState(); | |
| s.setup(); | |
| MyBenchmark b = new MyBenchmark(); | |
| int idx1 = b.java(s); | |
| int idx2 = b.boyerMoore(s); | |
| int w = s.HAYSTACK.length() - s.NEEDLE.length(); | |
| if (idx1 != w) System.out.println("java code broken"); | |
| if (idx2 != w) System.out.println("B-M code broken"); | |
| } | |
| @State(Scope.Benchmark) | |
| public static class MyState { | |
| public String NEEDLE, HAYSTACK; | |
| public byte[] _NEEDLE, _HAYSTACK; | |
| @Setup(Level.Trial) | |
| public void setup() { | |
| Charset cs = StandardCharsets.US_ASCII; | |
| byte[] base = "Hello, world! I am a string; perhaps I can ananate how, for ananananananars, and more!".getBytes(cs); | |
| byte[] answer = "ananas".getBytes(cs); | |
| _HAYSTACK = new byte[base.length * HAYSTACK_SIZE + answer.length]; | |
| _NEEDLE = answer; | |
| NEEDLE = new String(_NEEDLE, cs); | |
| for (int i = 0; i < HAYSTACK_SIZE; i++) System.arraycopy(base, 0, _HAYSTACK, base.length * i, base.length); | |
| System.arraycopy(answer, 0, _HAYSTACK, base.length * HAYSTACK_SIZE, answer.length); | |
| HAYSTACK = new String(_HAYSTACK, cs); | |
| } | |
| } | |
| @Benchmark | |
| public int java(MyState state) { | |
| return state.HAYSTACK.indexOf(state.NEEDLE); | |
| } | |
| @Benchmark | |
| public int boyerMoore(MyState state) { | |
| byte[] NEEDLE = state._NEEDLE, HAYSTACK = state._HAYSTACK; | |
| if (NEEDLE.length == 0) return 0; | |
| int[] ct = makeCharTable(NEEDLE); | |
| int[] ot = makeOffsetTable(NEEDLE); | |
| for (int i = NEEDLE.length - 1, j; i < HAYSTACK.length;) { | |
| for (j = NEEDLE.length - 1; NEEDLE[j] == HAYSTACK[i]; --i, --j) { | |
| if (j == 0) return i; | |
| } | |
| i += Math.max(ot[NEEDLE.length - 1 - j], ct[HAYSTACK[i]]); | |
| } | |
| return -1; | |
| } | |
| private static int[] makeCharTable(byte[] needle) { | |
| final int A = 128, len = needle.length; | |
| int[] t = new int[A]; | |
| Arrays.fill(t, len); | |
| for (int i = 0; i < len - 2; i++) t[needle[i]] = len - 1 - i; | |
| return t; | |
| } | |
| private static int[] makeOffsetTable(byte[] needle) { | |
| int len = needle.length; | |
| int[] t = new int[len]; | |
| int lastPrefixPosition = len; | |
| for (int i = len; i > 0; --i) { | |
| if (isPrefix(needle, i)) lastPrefixPosition = i; | |
| t[len - i] = lastPrefixPosition - i + len; | |
| } | |
| for (int i = 0; i < len - 1; i++) { | |
| int sLen = suffixLength(needle, i); | |
| t[sLen] = len - 1 - i + sLen; | |
| } | |
| return t; | |
| } | |
| private static boolean isPrefix(byte[] needle, int p) { | |
| for (int i = p, j = 0; i < needle.length; ++i, ++j) if (needle[i] != needle[j]) return false; | |
| return true; | |
| } | |
| private static int suffixLength(byte[] needle, int p) { | |
| int len = 0; | |
| for (int i = p, j = needle.length - 1; i >= 0 && needle[i] == needle[j]; --i, --j) len++; | |
| return len; | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | <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> | |
| <groupId>com.zwitserloot</groupId> | |
| <artifactId>boyermoore</artifactId> | |
| <version>1.0</version> | |
| <packaging>jar</packaging> | |
| <name>JMH benchmark sample: Java</name> | |
| <!-- | |
| This is the demo/sample template build script for building Java benchmarks with JMH. | |
| Edit as needed. | |
| --> | |
| <dependencies> | |
| <dependency> | |
| <groupId>org.openjdk.jmh</groupId> | |
| <artifactId>jmh-core</artifactId> | |
| <version>${jmh.version}</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>org.openjdk.jmh</groupId> | |
| <artifactId>jmh-generator-annprocess</artifactId> | |
| <version>${jmh.version}</version> | |
| <scope>provided</scope> | |
| </dependency> | |
| </dependencies> | |
| <properties> | |
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
| <!-- | |
| JMH version to use with this project. | |
| --> | |
| <jmh.version>1.22</jmh.version> | |
| <!-- | |
| Java source/target to use for compilation. | |
| --> | |
| <javac.target>1.8</javac.target> | |
| <!-- | |
| Name of the benchmark Uber-JAR to generate. | |
| --> | |
| <uberjar.name>benchmarks</uberjar.name> | |
| </properties> | |
| <build> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-compiler-plugin</artifactId> | |
| <version>3.8.0</version> | |
| <configuration> | |
| <compilerVersion>${javac.target}</compilerVersion> | |
| <source>${javac.target}</source> | |
| <target>${javac.target}</target> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-shade-plugin</artifactId> | |
| <version>3.2.1</version> | |
| <executions> | |
| <execution> | |
| <phase>package</phase> | |
| <goals> | |
| <goal>shade</goal> | |
| </goals> | |
| <configuration> | |
| <finalName>${uberjar.name}</finalName> | |
| <transformers> | |
| <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | |
| <mainClass>org.openjdk.jmh.Main</mainClass> | |
| </transformer> | |
| <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> | |
| </transformers> | |
| <filters> | |
| <filter> | |
| <!-- | |
| Shading signed JARs will fail without this. | |
| http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar | |
| --> | |
| <artifact>*:*</artifact> | |
| <excludes> | |
| <exclude>META-INF/*.SF</exclude> | |
| <exclude>META-INF/*.DSA</exclude> | |
| <exclude>META-INF/*.RSA</exclude> | |
| </excludes> | |
| </filter> | |
| </filters> | |
| </configuration> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| </plugins> | |
| <pluginManagement> | |
| <plugins> | |
| <plugin> | |
| <artifactId>maven-clean-plugin</artifactId> | |
| <version>2.5</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-deploy-plugin</artifactId> | |
| <version>2.8.1</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-install-plugin</artifactId> | |
| <version>2.5.1</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-jar-plugin</artifactId> | |
| <version>2.4</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-javadoc-plugin</artifactId> | |
| <version>2.9.1</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-resources-plugin</artifactId> | |
| <version>2.6</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-site-plugin</artifactId> | |
| <version>3.3</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-source-plugin</artifactId> | |
| <version>2.2.1</version> | |
| </plugin> | |
| <plugin> | |
| <artifactId>maven-surefire-plugin</artifactId> | |
| <version>2.17</version> | |
| </plugin> | |
| </plugins> | |
| </pluginManagement> | |
| </build> | |
| </project> | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment