Concurrent database query benchmark

Alex Averbuch alex.averbuch at neotechnology.com
Tue Jun 7 15:24:09 UTC 2016


Hi all,
This is my first question to the list -- please excuse the idiocy.

I am trying to write a benchmark that performs a very simple query against
a database, concurrently from a fixed number of threads.

The benchmark works fine with *@Threads( 1 )* but with *@Threads( 4 )* 3/4
threads find nothing in the database, as if it wasn't initialized or is a
different database.

When inspecting the database in *TxState.setUp()* I find that
*System.identityHashCode(db)* is always the same, as is the path to the
database, so I assume it is the same store -- a good thing.
However, *db.getRecordById( id )* then fails due to empty database -- a bad
thing.

Can anyone see a reason why the different *randomRecordById()* benchmark
method invocations would be receiving a different *db*?

Also, how many other mistakes am I making with this benchmark?

AFAIK, support for passing *ExampleDbBenchmark benchmarkState* into
*TxState.setUp()* is experimental, could this be the cause of my troubles?

Thanks in advance!
Alex


@State( Scope.Benchmark )
public class ExampleDbBenchmark
{
    public static final int RECORD_COUNT = 1_000_000;

    File dbDir;
    Database db;

    @Setup
    public void setUp() throws IOException
    {
        dbDir = Files.createTempDirectory( "bench-db" ).toFile();
        db = new Database( dbDir );
        populateDb( db );
    }

    void populateDb( Database db )
    {
        try ( Transaction tx = db.beginTx() )
        {
            for ( int i = 0; i < RECORD_COUNT; i++ )
            {
                db.createRecord( i );
            }
            tx.success();
        }
    }

    @TearDown
    public void tearDown() throws IOException
    {
        db.shutdown();
        FileUtils.deleteRecursively( dbDir );
    }

    @State( Scope.Thread )
    public static class TxState
    {
        ThreadLocalRandom rng;
        Transaction tx;
        Database db;

        @Setup
        public void setup( ExampleDbBenchmark benchmarkState ) throws
InterruptedException
        {
            this.rng = ThreadLocalRandom.current();
            this.db = benchmarkState.db;
            this.tx = db.beginTx();
        }

        @TearDown
        public void tearDown()
        {
            tx.close();
        }

    }

    @Benchmark
    @Threads( 4 )
    @BenchmarkMode( Mode.SampleTime )
    public Record randomRecordById( TxState txState )
    {
        long id = txState.rng.nextLong( 1, RECORD_COUNT );
        return txState.db.getRecordById( id );
    }
}


More information about the jmh-dev mailing list