java - Database Benchmark : Weird results when testing concurrency (ExecutorService) -
i developing java benchmark evaluate usecases (inserts, updates, deletes, etc.) apache derby database.
my implementation next :
after having warmed jvm, execute serie (for loop : (100k 1m iterations)) of, let's say, Ìnsert
in (single table @ moment) of database. apache derby, knows, test every mode (in memory/embedded, in memory/network, persistent/embedded, persistent/network)
the execution of process may singlethreaded, or multithreaded (using executors.newfixedthreadpool(poolsize)
well, here goes problem :
when execute benchmark 1 thread, have pretty realistics results
in memory/embedded[simple integer insert] : 35k inserts/second (1 thread)
then, decide execute 1 , 2 (concurrent) threads sequentially.
now, have next results :
in memory/embedded[simple integer insert] : 21k inserts/second (1 thread) in memory/embedded[simple integer insert] : 20k inserts/second (2 thread)
why results 1 thread alter much ?
basically, start , end timer before , after loop :
// processing long start = system.nanotime(); (int = 0; < loopsize; i++) { process(); } // end timer long abstime = system.nanotime() - start; double abstimemilli = abstime * 1e-6;
and process() method :
private void process() throws sqlexception { preparedstatement ps = clientconn.preparestatement(query); ps.setobject(1, val); ps.execute(); clientconn.commit(); ps.close(); }
as executions processed sequantially, reste of code (data handling) should not alter benchmark ?
the results go worse number of sequential threads grows (1, 2, 4, 8 example).
i sorry in advance if confusing. if needed, i'll provide more info or re-explain it!
thank you help :)
edit :
here method (from usecase class) calling aforementionned execution :
@override public arraylist<contextbean> bench(int loopsize, int poolsize) throws interruptedexception, executionexception { future<contextbean> t = null; arraylist<contextbean> cbl = new arraylist<contextbean>(); seek { executorservice es = executors.newfixedthreadpool(poolsize); (int = 0; < poolsize; i++) { benchexecutor = new benchexecutor(eds, insertstatement, loopsize, poolsize, "test-varchar"); t = es.submit(be); cbl.add(t.get()); } es.shutdown(); es.awaittermination(long.max_value,timeunit.milliseconds); } grab (interruptedexception e) { e.printstacktrace(); } grab (sqlexception e) { e.printstacktrace(); } homecoming cbl; }
on simple operations, every database behaves described.
the reason threads spawning seek operate on same table (or set of tables), database must serialize access.
in situation every thread works little slower, overall result (small) gain. (21k+20k=41k against 35k of single threaded version).
the gain decreases (usually exponentially) number of threads, , may experience loss, due lock escalation (see http://dba.stackexchange.com/questions/12864/what-is-lock-escalation).
generally, multithread solution gains when performance not bound single resource, multiple factors (i.e calculations, selects on multiple tables, inserts on different tables).
java concurrency benchmarking derby