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