tag:blogger.com,1999:blog-1124429072923386132024-03-08T14:16:14.097-08:00kasou.skkasouhttp://www.blogger.com/profile/05928340319416629796noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-112442907292338613.post-84614489276238695812007-01-19T08:52:00.000-08:002007-01-22T14:04:14.298-08:00JRuby JDBC performanceI'm writing server-side application (webchat) which communicates with DB.<br/> I wanted to use JRuby as the main implementation language, just rewrite som parts in pure java.<br/>So I intended to use with ActiveRecord-JDBC. I used H2 database in embedded mode.<br/><br/>My test simulates retrieving of last 10 rows in small table 1000 times in sequence.<br/>Every row is converted to set of custom classes which implent interfaces of business objects: ChatMessage containing MessageID, Sender, Recipient, MessageText,Timestamp, etc... <br/>There is previous java implementation of these interfaces, previous to decision of choosing JRuby.<br/><br/> As I sad first prototype used ActiveRecord. Every record was converted to set of java data classes. I used JRuby 0.9.2 and it took 3o seconds to run the test.<br/>After upgrade to trunk version from 2007-01-07 test sped up to 23 seconds.<br/>Great improvement, but still it wasn't fast enough.<br/>And after evaluation of pure Java performance it was really incredibly slow. Pure looping through JDBC ResultSet in Java took less than a second.<br/>On the other side, when I increased number of iterations 10x, AR took <strong>~700 seconds</strong>. You see, it's not linear. Java didn't have this problem: 5.5 seconds.<br/>I have switched to trunk version with first JIT compiler on Friday, and it really helps - just 210 seconds instead of 700. Still it consumes too much memory, but finally with usual linear behaviour (21 seconds for 1000 iterations).<br/><br/>So I decided to try some hybrid implementations. These were performed with 2 weeks old trunk version as this is the fastest for me ATM. <br/><ul><li>Ruby code calling raw JDBC interface with existing Java data classes: 114 seconds.<br/></li><li> The same ruby code but with new Ruby data classes (fresh implementations of same Java interfaces): 62 seconds.</li><li>Pure ruby code without any Java objects, assigning just to flat Hash: 40 seconds.<br/></li><li>Experimental replacement of direct JDBC calls with Java class wrapping DB row in Object[], multiple assigment to local variables: 40 seconds.</li><li>Same replacement returning HashMap instead of Object[]: 80 seconds.</li></ul>Quite various results, aren't they? I'm not sure, what is the brake here.<br/>I thought it could be because of converting from Ruby to Java and back, but I'm not sure yet. I tried keeping instances of Java objects in Hash not to construct them everytime, but it doesn't help a lot, just few seconds.<br/><br/>What to do next? I will try some metaprogramming hacks and mix ruby code generation with more universal Java wrappers to achieve good performance and configurability at the same time.<br/>kasouhttp://www.blogger.com/profile/05928340319416629796noreply@blogger.com2