Skip to content

Instantly share code, notes, and snippets.

@knutwannheden
Last active June 5, 2019 10:35
Show Gist options
  • Save knutwannheden/46a6982f45421e91824d3ccd5934c1e3 to your computer and use it in GitHub Desktop.
Save knutwannheden/46a6982f45421e91824d3ccd5934c1e3 to your computer and use it in GitHub Desktop.
package org.jooq.test.benchmark;
import java.util.ArrayList;
import java.util.List;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
@Fork(value = 3, jvmArgsAppend = "-Djmh.stack.lines=3")
@Warmup(iterations = 5, time = 3)
@Measurement(iterations = 7, time = 3)
public class ParseIntBenchmark {
public enum ValueDistribution {
HAPPY_PATH, EVEN_SPLIT, SAD_PATH
}
@State(Scope.Benchmark)
public static class BenchmarkState {
@Param({ "HAPPY_PATH", "EVEN_SPLIT", "SAD_PATH" })
ValueDistribution distribution;
List<String> list = new ArrayList<>();
@Setup(Level.Trial)
public void setup() throws Exception {
for (int i = 10_000_000; i < 10_010_000; i++) {
String s = Integer.toString(i);
switch (distribution) {
case HAPPY_PATH:
list.add(s);
break;
case EVEN_SPLIT:
list.add((i & 1) == 1 ? s : s + '#');
break;
case SAD_PATH:
list.add(s + '#');
break;
}
}
}
@TearDown(Level.Trial)
public void teardown() throws Exception {
list = null;
}
}
@Benchmark
public void testIntegerValueOf(Blackhole blackhole, BenchmarkState state) {
for (int i = 0; i < state.list.size(); i++) {
try {
blackhole.consume(Integer.valueOf(state.list.get(i)));
} catch (NumberFormatException e) {
blackhole.consume(null);
}
}
}
@Benchmark
public void testTryParseInt(Blackhole blackhole, BenchmarkState state) {
for (int i = 0; i < state.list.size(); i++) {
blackhole.consume(tryParseInt(state.list.get(i)));
}
}
// adapted from com.google.common.primitives.Longs#tryParse()
static Integer tryParseInt(String string) {
if (string == null || string.isEmpty())
return null;
int radix = 10;
char firstChar = string.charAt(0);
boolean negative = firstChar == '-';
int index = negative || firstChar == '+' ? 1 : 0;
int length = string.length();
if (index == length)
return null;
int digit = Character.digit(string.charAt(index++), 10);
if (digit < 0 || digit >= radix)
return null;
int accum = -digit;
int cap = Integer.MIN_VALUE / radix;
while (index < length) {
digit = Character.digit(string.charAt(index++), 10);
if (digit < 0 || digit >= radix || accum < cap)
return null;
accum *= radix;
if (accum < Integer.MIN_VALUE + digit)
return null;
accum -= digit;
}
if (negative)
return accum;
else if (accum == Integer.MIN_VALUE)
return null;
else
return -accum;
}
// adapted from com.google.common.primitives.Longs#tryParse()
static Long tryParseLong(String string) {
if (string == null || string.isEmpty())
return null;
int radix = 10;
char firstChar = string.charAt(0);
boolean negative = firstChar == '-';
int index = negative || firstChar == '+' ? 1 : 0;
int length = string.length();
if (index == length)
return null;
int digit = Character.digit(string.charAt(index++), 10);
if (digit < 0 || digit >= radix)
return null;
long accum = -digit;
long cap = Long.MIN_VALUE / radix;
while (index < length) {
digit = Character.digit(string.charAt(index++), 10);
if (digit < 0 || digit >= radix || accum < cap)
return null;
accum *= radix;
if (accum < Long.MIN_VALUE + digit)
return null;
accum -= digit;
}
if (negative)
return accum;
else if (accum == Long.MIN_VALUE)
return null;
else
return -accum;
}
}
@knutwannheden
Copy link
Author

knutwannheden commented Jun 5, 2019

My results when running this benchmark:

Benchmark                             (distribution)   Mode  Cnt     Score      Error  Units
ParseIntBenchmark.testIntegerValueOf      HAPPY_PATH  thrpt    5  4220.672 ± 1267.448  ops/s
ParseIntBenchmark.testIntegerValueOf      EVEN_SPLIT  thrpt    5   142.986 ±    7.836  ops/s
ParseIntBenchmark.testIntegerValueOf        SAD_PATH  thrpt    5    77.191 ±    7.297  ops/s
ParseIntBenchmark.testTryParseInt         HAPPY_PATH  thrpt    5  4685.361 ±  345.036  ops/s
ParseIntBenchmark.testTryParseInt         EVEN_SPLIT  thrpt    5  4082.392 ±  493.595  ops/s
ParseIntBenchmark.testTryParseInt           SAD_PATH  thrpt    5  4437.445 ±   44.599  ops/s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment