Thursday, 15 May 2014

java - Database insertion is taking zero seconds to insert -



java - Database insertion is taking zero seconds to insert -

i trying measure performance of database insert. have written stopwatch class reset counter before executeupdate method , calculate time after executeupdate method done.

and trying see how much time each thread taking, keeping numbers in concurrenthashmap.

below main class-

public static void main(string[] args) { final int noofthreads = 4; final int nooftasks = 100; final atomicinteger id = new atomicinteger(1); executorservice service = executors.newfixedthreadpool(noofthreads); (int = 0; < nooftasks * noofthreads; i++) { service.submit(new task(id)); } while (!service.isterminated()) { } //printing histogram system.out.println(task.histogram); }

below class implements runnable in trying measure each thread performance in inserting database meaning how much time each thread taking insert database-

class task implements runnable { private final atomicinteger id; private stopwatch totalexectimer = new stopwatch(task.class.getsimplename() + ".totalexec"); public static concurrenthashmap<long, atomiclong> histogram = new concurrenthashmap<long, atomiclong>(); public task(atomicinteger id) { this.id = id; } @override public void run() { dbconnection = getdbconnection(); preparedstatement = dbconnection.preparestatement(constants.insert_oracle_sql); //other preparedstatement totalexectimer.resetlap(); preparedstatement.executeupdate(); totalexectimer.accumulatelap(); final atomiclong before = histogram.putifabsent(totalexectimer.getcumulativetime() / 1000, new atomiclong(1l)); if (before != null) { before.incrementandget(); } } }

below stopwatch class

/** * simple stop watch. */ protected static class stopwatch { private final string name; private long lapstart; private long cumulativetime; public stopwatch(string _name) { name = _name; } /** * resets lap start time. */ public void resetlap() { lapstart = system.currenttimemillis(); } /** * accumulates lap time , homecoming current lap time. * * @return current lap time. */ public long accumulatelap() { long laptime = system.currenttimemillis() - lapstart; cumulativetime += laptime; homecoming laptime; } /** * gets current cumulative lap time. * * @return */ public long getcumulativetime() { homecoming cumulativetime; } public string getname() { homecoming name; } @override public string tostring() { stringbuilder sb = new stringbuilder(); sb.append(name); sb.append("="); sb.append((cumulativetime / 1000)); sb.append("s"); homecoming sb.tostring(); } }

after running above program, can see 400 rows got inserted. , when printing histogram, seeing this-

{0=400}

which means 400 calls came in 0 seconds? it's not possible sure.

i trying see how much time each thread taking insert record , store numbers in map , print map main thread.

i think problem assuming it's happening because of thread safety here , reason whenever doing resetlap 0 getting set map guess.

if yes how can avoid problem? , required pass histogram map main thread constructor of task? need print map after threads finished see numbers there.

update:- if remove divide 1000 thing store number milliseconds able see numbers apart zero. looks good.

but 1 thing more found out numbers not consistent, if sum each threads time, number that. , printing how much time in whole programme finishing well. compare these 2 numbers different big margin

to avoid concurrency issues stopwatch you're improve off creating new 1 local variable within run method of runnable. way each thread has it's own stopwatch.

as timing you're seeing, absolutely hope simple record insert happen in under second. seeing 400 inserts happen in less sec each doesn't surprise me @ all. may improve results using millisecond value stopwatch hashmap key.

update

for stopwatch concurrency problem i'm suggesting this:

class task implements runnable { private final atomicinteger id; // remove stopwatch here //private stopwatch totalexectimer = new stopwatch(task.class.getsimplename() + ".totalexec"); public static concurrenthashmap<long, atomiclong> histogram = new concurrenthashmap<long, atomiclong>(); public task(atomicinteger id) { this.id = id; } @override public void run() { // , add together here stopwatch totalexectimer = new stopwatch(task.class.getsimplename() + ".totalexec"); dbconnection = getdbconnection();

in way each thread, indeed each task, gets own copy, , don't have worry concurrency. making stopwatch thread-safe as-is more problem it's worth.

update 2

having said approach mentioned in comment give improve results, there's less overhead in timing mechanism.

to reply question difference in cumulative thread time , toal running time of programme glibbly say, "what did expect?".

there 2 issues here. 1 you're not measuring total running time of each thread, bit you're doing db insert.

the other measuring running time of whole application not take business relationship overlap in execution times of threads. if measuring total time of each task, , assuming you're running on multi-core machine, expect cumulative time more elapse time of programme execution. that's benefit of parallel programming.

java database multithreading

No comments:

Post a Comment