Here's my current code for benchmarking. Does this seem correct to you?


On 27/10/2016 14:55, Peter Levart wrote:


On 10/27/2016 03:48 PM, Peter Levart wrote:

On 10/27/2016 02:20 PM, Brunoais wrote:

Hey.

Any idea how to skip tests? When testing for BufferedInputStream, the directBufferSize is not used so testing with different directBufferSize makes no sense.

I already tried "return 0" on the benchmarked test but jmh fills the output with " (*interrupt*)" if I do that.


If all combinations of @Param(s) don't make sense then I usually collapse two or three of them into one "compound" @Param containing the sensible combinations of their components. The type of such @Param field is String and the content is a delimited multi-value tuple. the @Setup method then parses such tuple into components...

Regards, Peter


Another possibility is to invoke the test(s) with command-line overrides for values of particular parameters. The benchmark will then run just the combinations you specify on the command line (try: java -jar benchmarks.jar -help).

Peter


package org.sample.BufferedNon_BlockIO;

import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
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.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

/**
 * A sample file reading benchmark
 */
@BenchmarkMode(Mode.SingleShotTime)
@Fork(value = 1)
@Warmup(iterations = 0, time = 2, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 2)
@Threads(1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class BufferedNonBlockStreamBenchmark_try1 {

        public static boolean isWindows = 
System.getProperty("os.name").contains("Windows");
        
    @Param({"1gig_file"})
    String file;

//    @Param({"4100", "16400", "131100", "1048600"})
    @Param({"4100", "131100", "1048600"})
    int javaBufSize;
    
    @Param({"100", "1000"})
    int readSize;

//    @Param({"0", "1000", "100000"})
    @Param({"0", "1000"})
    long cpuWork;

    //                                                                          
                This MUST be smaller than javaBufSize
    //                                                                          
                @Param({"4096", "16384", "131072", "1048576"})
    @Param({"BufferedInputStream", "BufferedNonBlockStream|4096", 
"BufferedNonBlockStream|131072", "BufferedNonBlockStream|1048576"})
    String implType;

    interface ReadOp {
        int read(byte[] buf) throws IOException;
    }

    private ReadOp read;
    private Closeable close;
    private byte[] buf;

    @Setup(Level.Iteration)
    public void setup() throws IOException, InterruptedException {

        clearCache();
        
        String[] type_readSize = implType.split("\\|");

        switch (type_readSize[0]) {
            case "BufferedInputStream":{
                BufferedInputStream in = new BufferedInputStream(
                    new FileInputStream(file), javaBufSize);
                read = in::read;
                close = in::close;
            }
                break;
            case "BufferedNonBlockStream": {
                BufferedNonBlockStream in = new BufferedNonBlockStream(
                                FileChannel.open(new File(file).toPath()), 
javaBufSize, Integer.parseInt(type_readSize[1]));
                read = in::read;
                close = in::close;
            }
            break;
            default:
                throw new IllegalArgumentException(
                    "Invalid parameter 'implType': " + implType);
        }

        buf = new byte[readSize];
    }

    @TearDown(Level.Iteration)
    public void tearDown() throws IOException {
        close.close();
    }

    /**
     * 
     * For linux:
     * 
     * Compile the following C program into clear_cache executable:
     * <pre>{@code
     *
     * #include <stdio.h>
     * #include <string.h>
     * #include <errno.h>
     *
     * #define PROC_FILE "/proc/sys/vm/drop_caches"
     *
     * int main(char *argv[], int argc) {
     *   FILE *f;
     *   f = fopen(PROC_FILE, "w");
     *   if (f) {
     *     fprintf(f, "3\n");
     *     fclose(f);
     *     return 0;
     *   } else {
     *     fprintf(stderr, "Can't write to: %s: %s\n", PROC_FILE, 
strerror(errno));
     *     return 1;
     *   }
     * }
     *
     * }</pre>
     * ... and make it SUID root!
     * 
     * For windows:
     * Use the provided clear_cache.exe
     * (source code and original author:)
     * https://gist.github.com/bitshifter/c87aa396446bbebeab29
     * Then run this program with administrator privileges
     */
    private static void clearCache() throws IOException, InterruptedException {
        // spawn an OS command to clear the FS cache...
        if(isWindows){
                new ProcessBuilder("clear_cache.exe").start().waitFor();
        } else {
                new ProcessBuilder("clear_cache").start().waitFor();            
        
        }
    }

    @Benchmark
    public int testRead() throws IOException {
        int nread = 0;
        int n;
        while ((n = read.read(buf)) >= 0) {
            nread += n;
            Blackhole.consumeCPU(cpuWork);
        }
        return nread;
    }
}

Reply via email to