-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: A question about Hibernate performace
PostPosted: Fri Sep 19, 2003 9:46 am 
Newbie

Joined: Fri Sep 19, 2003 5:06 am
Posts: 4
Hi all,
I'm evaluating Hibernate as OR mapping framework. I order to understand what the real overhead id I wrote this program:

package it.noematica;

import java.util.Iterator;
import java.util.List;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
import org.apache.log4j.Logger;

public class HibernateTest {
private static Logger logger=Logger.getLogger(HibernateTest.class.getName());
public static void main(String[] args)throws Exception {
HibernateTest hibernateTest = new HibernateTest();
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection
("jdbc:oracle:thin:@server:1521:ORCL", "xxxx", "xxxx");
Statement st=conn.createStatement();
logger.debug("Started");
long start=System.currentTimeMillis();
ResultSet rs=st.executeQuery("Select * from db_obj");
while (rs.next()) {
rs.getString("OBJECT_NAME");
//System.out.println("dbobj: name " + rs.getString("OBJECT_NAME"));
}
long end=System.currentTimeMillis();
logger.fatal("elapsed " + (end-start));
//Configuration cfg=new Configuration().addClass(DbObj.class);
//cfg.configure();
//SessionFactory factory=cfg.buildSessionFactory();
SessionFactory factory=new Configuration().configure().buildSessionFactory();
Session session=factory.openSession();
session.beginTransaction();
start=System.currentTimeMillis();
Query query=session.createQuery("from it.noematica.DbObj as dbobj");
for (Iterator it = query.iterate(); it.hasNext();) {
DbObj dbobj = (DbObj) it.next();
dbobj.getObjectName();
//System.out.printlnln("dbobj: name " + dbobj.getObjectName());
}
end=System.currentTimeMillis();
logger.fatal("elapsed " + (end-start));

}
}

ther result are very strange
Resultset:
4306msec
Hibernate
1139538msec
I noted that Hibernate first loads all ids and then
loads the row one by one.
Can anyone tell me how to interpret this and how to get better results?
Thanks in advance,
Giovanni


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 19, 2003 11:19 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
I'd have to see your mapping to give a fully response. But in the code you pasted, for the hibernate test, you are using the Query.iterate() method. Its behavior is exactly what you saw. First it loads all entity ids matching the query, then as you progress through the iterator each entity is loaded "on demand". Instead, try the Query.list() method. It loads all entities matching the query immediately. Over an entire result set it is usually much faster.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 22, 2003 2:46 am 
Newbie

Joined: Fri Sep 19, 2003 5:06 am
Posts: 4
Thank you,
I modified the my sample and now the times are comparable
4426 vs 9323
here is my mapping
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

<class name="it.noematica.DbObj" table="db_obj">
<id name="id" type="integer" unsaved-value="null" >
<column name="OBJECT_ID" sql-type="integer" not-null="true"/>
<generator class="assigned"/>
</id>

<!-- A cat has to have a name, but it shouldn' be too long. -->
<property name="owner" not-null="true"/>
<property name="objectName" column="OBJECT_NAME" not-null="true"/>
<property name="subobjectName" column="SUBOBJECT_NAME" />
<property name="dataObjectId" type="integer" column="DATA_OBJECT_ID" not-null="true"/>
<property name="objectType" column="OBJECT_TYPE" />
<property name="created" type="timestamp" column="CREATED" not-null="true"/>
<property name="lastDDLTime" type="timestamp" column="LAST_DDL_TIME" not-null="true"/>
<property name="timestamp" column="TIMESTAMP" />
<property name="status" column="STATUS" />
<property name="temporary" column="TEMPORARY" />
<property name="generated" column="GENERATED" />
<property name="secondary" column="SECONDARY" />
</class>

</hibernate-mapping>
and here is my hibernate.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- <property name="connection.datasource">java:comp/env/jdbc/quickstart</property> -->
<property name="show_sql">false</property>
<property name="use_outer_join">false</property>
<property name="cglib.use_reflection_optimizer">false</property>
<property name="dialect">net.sf.hibernate.dialect.OracleDialect</property>
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@server:1521:ORCL</property>
<property name="connection.username">xxxx</property>
<property name="connection.password">xxxx</property>

<!-- Mapping files -->
<mapping resource="dbobj.hbm.xml"/>

</session-factory>

</hibernate-configuration>
Is it possible to further speed up the execution of my sample?
Thanks in advance,
Giovanni


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 22, 2003 6:49 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
If you do this correctly (ie. do the measurements in a loop), you will see no performance difference b/w Hibernate and direct JDBC.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 22, 2003 9:41 am 
Newbie

Joined: Fri Sep 19, 2003 5:06 am
Posts: 4
Hi,
Now with code provided in my previous message of this topic hibernate takes twice as jdbc.
I' don't know why and I'd like to know if is it possible to get similar executions time.
I suppose that much of the time is spent in creating objects and or parsing the query. Is it correct?
Thanks in advance,
Giovanni


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 22, 2003 12:04 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
It not going to be possible to get the same execution times. Hibernate is using JDBC underneath and so is going to inherit the time it took JDBC to process something plus the time it takes Hibernate to "hydrate" the entity from the JDBC result set.

However, unless you are planning on returning result sets directly to the clients, you are basically skewing the performance results. The typical approach in java apps (j2ee or otherwise) is to read data from result sets and populate java objects (typically java beans) from those results. Hibernate takes make this extra step for you and givens you incredible benefits in return. So unless you plan to use the disconnected row-set approach, its better to set up your performance tests more appropriately to account for that transfer.

What Gavin mentions is to perform the queries in a loop. Basically execute the direct JDBC stuff 10 times and record the results. The execute the Hibernate stuff 10 times and record results. Then the performace will be much closer.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 23, 2003 1:46 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I insist that if you do your performance tests *properly* - and the code you have shown is complete garbage - you will measure no difference for this case. I know this, because I have done many similar performance tests. For example, look at net.sf.hibernate.test.PerformanceTest, which demonstrates how to do these kind of tests properly.

Note also, that your JDBC test does not even execute the same SQL as Hibernate, nor does it properly pull all the data from the ResultSet.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.