0

I have file with some amount of different strings (about 100.000 taken from prod). Need to find out 99%, 99.9% for function that process each string from that file.

I've tried to use jmh to write benchmark. However, I was able to find out required percentiles only for batch function (that process the whole file) or only for required function with one particular string.

public String process1(String str){
    ...process...
}

public String processBatch(List<String> strings){
    for (String str: strings){
        process1(str)
    }
}

also, i've tried to set the whole list of strings by @param. That makes jmh to run dozens of iterations for each string, but not to find required results.

Is there anything in jmh that can help to find required statistics? If not, what tool can be used for this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Natalia
  • 4,362
  • 24
  • 25
  • @CConard96 thanks, I've checked that info in the begining. But failed to find information how to run particular benchmark – Natalia May 15 '16 at 20:35

1 Answers1

2

Is it what you are looking for?

@Warmup(iterations = 1, time = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 1, time = 5, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Benchmark)
public class MyBenchmark {

    ClassUnderBenchmark classUnderBenchmark = new ClassUnderBenchmark();

    @State(Scope.Benchmark)
    public static class MyTestState {

        int counter = 0;
        List<String> list = Arrays.asList("aaaaa", "bbbb", "ccc");
        String currentString;

        @Setup(Level.Invocation)
        public void init() throws IOException {
            this.currentString = list.get(counter++);
            if (counter == 3) {
                counter = 0;
            }
        }
    }

    @Benchmark
    @Threads(1)
    @BenchmarkMode(Mode.SampleTime)
    public void test(MyBenchmark.MyTestState myTestState) {
        classUnderBenchmark.toUpper(myTestState.currentString);
    }

    public static class ClassUnderBenchmark {

        Random r = new Random();

        public String toUpper(String name) {
            try {
                Thread.sleep(r.nextInt(100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return name.toUpperCase();
        }
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(MyBenchmark.class.getSimpleName())
                .jvmArgs("-XX:+UseG1GC", "-XX:MaxGCPauseMillis=50")
                .build();
        new Runner(opt).run();
    }
}

Please see the javadoc (org.openjdk.jmh.annotations.Mode):

/**
 * <p>Sample time: samples the time for each operation.</p>
 *
 * <p>Runs by continuously calling {@link Benchmark} methods,
 * and randomly samples the time needed for the call. This mode automatically adjusts the sampling
 * frequency, but may omit some pauses which missed the sampling measurement. This mode is time-based, and it will
 * run until the iteration time expires.</p>
 */
SampleTime("sample", "Sampling time"),

This test will give you the output:

Result "test":

  N = 91
  mean =      0,056 ±(99.9%) 0,010 s/op

  Histogram, s/op:
    [0,000, 0,010) = 6 
    [0,010, 0,020) = 9 
    [0,020, 0,030) = 3 
    [0,030, 0,040) = 11 
    [0,040, 0,050) = 8 
    [0,050, 0,060) = 11 
    [0,060, 0,070) = 9 
    [0,070, 0,080) = 9 
    [0,080, 0,090) = 14 

  Percentiles, s/op:
      p(0,0000) =      0,003 s/op
     p(50,0000) =      0,059 s/op
     p(90,0000) =      0,092 s/op
     p(95,0000) =      0,095 s/op
     p(99,0000) =      0,100 s/op
     p(99,9000) =      0,100 s/op
     p(99,9900) =      0,100 s/op
     p(99,9990) =      0,100 s/op
     p(99,9999) =      0,100 s/op
    p(100,0000) =      0,100 s/op


Benchmark           Mode  Cnt  Score   Error  Units
MyBenchmark.test  sample   91  0,056 ± 0,010   s/op
phuclv
  • 37,963
  • 15
  • 156
  • 475
Adam Dec
  • 32
  • 1