-->
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.  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Hibernate performance very poor compare with JDO
PostPosted: Fri Jan 14, 2005 2:46 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
Hi,

We are thinking in migrating from EJB2 to Hibernate.

I am new to Hibernate, and (for my surprise) in few minuts I have
my first Hibernate run against a AS/400. That is good.

But the performance test was a deception for me:
[Hibernate] quantity=77327 records, total time=120165ms, speed=643 records/second
[JDO] quantity=77327 records, total time=70814ms, speed=1091 records/second
[JDBC] quantity=77327 records, total time=59011ms, speed=1310 records/second

The performance of JDO (a open source implementation) is near JDBC,
but Hibernate... slow.

I not tune nothing in JDO,
and tuning my ejb server (JBoss 3.2.x) I can run at 900 records/seconds with
EntityBeans.

Some tip to tune hibernate to run more fast.

Thank you in advance



Hibernate version: : 2.1.7c

Mapping documents:
Code:
<hibernate-mapping package="puntocom.persistencia.hibernate">

  <class
     name="TerceroH"
     table="G4GENBD.GENTGR">
 
    <id name="oid" type="long" column="TGRNRR">
         <generator class="assigned"/>
      </id>
      
      <property name="nif" column="TGRNIF"/>
      <property name="nombre" column="TGRDEN"/>
      
  </class>

</hibernate-mapping>



Code between sessionFactory.openSession() and session.close():
Code:
      net.sf.hibernate.Transaction tx = session.beginTransaction();
      
      net.sf.hibernate.Query query = session.createQuery("select t from TerceroH as t");
      //query.setFetchSize(50); // tmp            
      query.setMaxResults(maximo);
      List lista = query.list();
      
      //List lista = session.find("select t from TerceroH as t");
      
      for (Iterator it = lista.iterator(); it.hasNext();) {
          TerceroH tercero = (TerceroH) it.next();
          tercero.getNombre();
          //System.out.println("Tercero: " + tercero.getNombre());
          cantidad++;
          if (cantidad >= maximo) break;
      }

      tx.commit();


Full stack trace of any exception that occurs:

Name and version of the database you are using:
AS/400 V5R2

The generated SQL (show_sql=true):
select terceroh0_.TGRNRR as TGRNRR, terceroh0_.TGRNIF as TGRNIF, terceroh0_.TGRDEN as TGRDEN from G4GENBD.GENTGR terceroh0_ fetch first 80000 rows only
Code:
Code:


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 14, 2005 5:34 pm 
Regular
Regular

Joined: Tue Jun 22, 2004 8:01 pm
Posts: 106
Location: PowderTown, Utah, USA
You sure you're comparing apples to apples here? For one thing, who knows what's faster about JDO in your example, we don't know what the JDO sample is doing. Also, in just a straight read test, JDBC may outperform Hibernate, but in a real application I've seen Hibernate outperform my own JDBC proprietary persistence framework many times over. The reason is that Hibernate is optimized for use in an application and can take advantage of things like the first and second level cache, lazy loading of collections, discreet rowset loading, and proxies.

I don't think you can make a blanket statement about Hibernate being slow by just running a few thousand reads through it. It's just not a fair comparison. BTW, I don't think you'll get a ton of replies by posting with a subject like "Hibernate performance very poor..." Most of us have had very good experience with Hibernate's performance, so statements like that appear very uninformed.

Once you've done some research and homework, I'm sure plenty of folks will be willing to help you tune up your app.


Top
 Profile  
 
 Post subject: Sorry, I only want tune up hibernate
PostPosted: Mon Jan 17, 2005 6:11 am 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
Sorry,

I do not want go against hibernate and I do not want to hurt the pride of anybody.

My goal is use hibernate instead of EJB2, but when I try read 70000 records
I see that the performance is poor.
I obtain better performance with JDO and EJB2, and I know that hibernate is
very fast. I'm sure that is a configuration problem.

I have more test of performace for do with hibernate. But the test of read a
large amount of record is very important; because in real application
(note that a AS/400, now i5, is a powerful and expensiver server, not a toy)
read a large amount of records for do some logic on each is normal.

In addition, the double of time to read 70000 records is too much.
Surely it is easy to configure hibernate to run well against as400.

P.D.: The JDO that run fast here:
Code:
         manager.currentTransaction().begin();
         javax.jdo.Query query = manager.newQuery(TerceroJDO.class);
         if (condicion != null) {            
            query.setFilter(condicion);
         }

         Collection terceros = (Collection)query.execute();
         Iterator it = terceros.iterator();
         while (it.hasNext()) {
            TerceroJDO tercero = (TerceroJDO) it.next();
            tercero.getOid();
            tercero.getNif();
            tercero.getNombre();                         
            cantidad++;            
            if (cantidad >= maximo) break;
         }
         manager.currentTransaction().commit();


As you see, is the same that the Hibernate

Somobody know how to configure hibernate to run faster agains as400?

Thank you in advance


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 7:33 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
have you search forum for questions like this?

are the 7000 record going to be updated? if not, you must read the doc, wiki and hibernate in action of course

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 8:42 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Why are you arguing with this guy about his useless test. We have an FAQ and an essay:

http://www.hibernate.org/Documentation/PerformanceQA
http://www.hibernate.org/Documentation/Benchmarks

That explains it all.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 3:04 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
Quote:

Why are you arguing with this guy about his useless test. We have an FAQ and an essay:

http://www.hibernate.org/Documentation/PerformanceQA
http://www.hibernate.org/Documentation/Benchmarks

That explains it all


I read this links and I didn't found somthing util for tune up my test.
I read the documentation and I try to:
session.setFlushMode(FlushMode.COMMIT);
iterate(), scroll(), criteria, query, etc. etc.
I put lazy="true" in mapping declaration
etc, etc.
But the test run slow

I read others thread, and I found other person with the same problem,
but the response of thread is 'your test is useless, Hiberante is the fast'

I don't say that hibernate is bad, I only want help to tune up.

Please give me a practical help, anything to try, no tell me
'Hibernate is slow reading simple tables but fast in complicate cases'
The simple case no is useless, the simple case (reading a big table) is common.

What happens inside query.list()?
Only read and load in objects?
Why JDBC and JDO (a Open Source Implementation) is double faster?

I want to tune up hiberante to run fast again as400.
I don't want to criticize Hibernate.
Please not tell me: 'Your test is useless hibernate is big'

Somebody can help me?

Thank you in advance[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 3:12 pm 
Regular
Regular

Joined: Tue Jun 22, 2004 8:01 pm
Posts: 106
Location: PowderTown, Utah, USA
1. Turn on Hibernate SQL output. Check the query that's being generated to make sure it's fast. Perhaps it does things differently than your JDO and JDBC solutions do. There may be some joining that needs changing.

2. Turn on Hibernate's logging (use log4j properties file) and make sure you're logging the milliseconds between log entries.

3. Carefully analyze exactly which part or parts of Hibernate take the longest. This process will not only teach you a great deal about hibernate, but it will help you identify what your potential bottleneck is.

4. Make a plan to optimize.

After all this, if you've got questions, then post.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 3:17 pm 
Newbie

Joined: Wed Sep 01, 2004 1:32 pm
Posts: 9
Location: (eastern) North Carolina
Your code has a batch like charactor to it. There is a blog entry that I recall not too long ago that might be applicable to your issue.

http://blog.hibernate.org/cgi-bin/blosxom.cgi/Gavin%20King/batch.html

Don't give up on Hibernate!

Best Regards, Jim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 3:19 pm 
Newbie

Joined: Wed Sep 01, 2004 1:32 pm
Posts: 9
Location: (eastern) North Carolina
feester wrote:
Your code has a batch like character to it. There is a blog entry that I recall not too long ago that might be applicable to your issue.

http://blog.hibernate.org/cgi-bin/blosxom.cgi/Gavin%20King/batch.html

Don't give up on Hibernate!

Best Regards, Jim


Top
 Profile  
 
 Post subject: Step back for a second
PostPosted: Mon Jan 17, 2005 4:36 pm 
Newbie

Joined: Thu Aug 05, 2004 11:00 pm
Posts: 7
Location: New York, NY
I think we need to ask Javier to step back for a moment and question why it matters that Hibernate can't read 70,000 records as fast as he would like to see them read. What kind of app would have such a requirement? Does his app actually have a requirement to display to the end-user 70,000 records of frequently-changing data on one screen at a time? No interactive apps I've ever written need to do anything like that.

On the other hand, if he's trying to write a bulk update or backup script then Hibernate is probably not the best tool for that type of thing, and he should use the database's native tools and extensions.

_________________
When asked by a reporter what he thought of western civilization, Mahatma Ghandi once replied that he thought it would be a good idea.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 17, 2005 5:29 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Feester is correct. Simply apply the simple instructions in the blog entry, and Hibernate exhibits minimal overhead compared to direct JDBC.

Or course, 70 000 records is not the typical usecase for on online application. It is a "special case".


Top
 Profile  
 
 Post subject: Still slow
PostPosted: Wed Jan 19, 2005 1:12 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
Hi,

hibernate still run slow.
I first tried to configure hibernate in hibernate.properties (hibernate.jdbc.batch_size included) and nothing happened.

Then, I download the last sourcecode from CVS and start to debug for
find the performance problem.

And I found that the problem is in the method Loader.getRow()
when I change the implementation of this method for a creation of my object
and direct population of the properties from ResultSet than everything
run fast, very fast (90% of JDBC).
I tried to found the exact problem, but when I begin to put the original
code little by little, the performance decrease little by little. Hence I think
that is the sum of all hidrate process, that affect the performance.

Maybe the problem is in another place... I don't know

I test with sun and jrockit jdk, and with hibernate 2.1.6, 2.1.7 and CVS HEAD.

Is peculiar for me that this lightweight framework (at least reading records)
go 50% of JDBC performance while I win to run EJB CMP2 at 90% JDBC performace
with JBoss and WebSphere. And with no tune I run JDO near JDBC.

In any case I understand that hibernate is 'de facto' standard for persistence
and surely I go in this way. But at momment not with good flavor of mouth.

Thank you


Top
 Profile  
 
 Post subject: To read 70 000 is a typical usage
PostPosted: Wed Jan 19, 2005 1:30 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
Hi Gavin,

Quote:
Or course, 70 000 records is not the typical usecase for on online application. It is a "special case"


Maybe that in internet applicaction thats is this the case.
But think that the E in J2EE is Enterprise, and some companies use this
tecnology for create Critical Business Applicactions, the type of applicactions
that before was wrote with COBOL or RPG.

A tipical process is search in a table 2 or 3 millions of records, then iterate
on the result (large too, but smaller) and do logic in each record;
maybe a end of this we need to
create a plain text file for send to Bank. In my company the java programmers
do this type of process.

Why not use direct JDBC for this? Simply. The logic to apply is complex and
we love OOP, and we prefer to put the logic and a class, otherwise we go to
procedural programming (ugly).
Why not use RPG? Portability, We need run our applications out of AS/400 for some customers.

For this type of process reading fast simple records is important,
and at momment I win this using EntityBeans. Why not with Hibernate?

Maybe the problem is Hibernate + AS400?

Cheers!
Javi


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 19, 2005 2:03 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
You know, in the last few days and weeks you tried to run your own code you could've also had a look at Hibernate some more. There is a very trivial (much like yours) performance test target in the build.xml. Call that with your database settings and see what it does in the code. Hibernate should show minimal overhead, as expected by everyone, and sometimes even be faster.

I'll add it to the FAQ.


Top
 Profile  
 
 Post subject: FYI
PostPosted: Sat Jan 22, 2005 2:06 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I just did some performance tests to compare query performance of Hibernate vs a very well-known leading JDO solution. Here is the code. Note that I don't claim I had the JDO solution configured perfectly, there may be settings I don't know about. (However, I did not do anything exotic to Hibernate either.)

Code:
   public static void main(String[] args) {
      PersistenceManagerFactory pmf = [CENSORED!];
      SessionFactory sf = new Configuration()
         .addClass(Foo.class)
         .buildSessionFactory();
      
      System.out.println("5000 rows");
      
      for ( int j=0; j<5; j++ ) {
      
         long hb = 0;
         long hbstart = System.currentTimeMillis();
         
         for ( int i=0; i<30; i++ ) {
         
            Session s = sf.openSession();
            s.setFlushMode(FlushMode.NEVER);
            Transaction t = s.beginTransaction();
            long ht = System.currentTimeMillis();

            List result2 = s.createQuery("from Foo")
               //.setReadOnly(true)
               .list();

            hb += System.currentTimeMillis() - ht;
            t.commit();
            s.close();
         
         }
         
         long hbtotal = System.currentTimeMillis() - hbstart;
         
         System.out.println("Hibernate: queries=" + hb + ", total=" + hbtotal);
   
         long jodo = 0;
         long jdstart = System.currentTimeMillis();
         
         for ( int i=0; i<30; i++ ) {
         
            PersistenceManager pm = pmf.getPersistenceManager();
            pm.currentTransaction().begin();
            long jt = System.currentTimeMillis();

            Object result = pm.newQuery(Foo.class).execute();

            jodo += System.currentTimeMillis() - jt ;
            pm.currentTransaction().commit();
            pm.close();
         
         }
         
         long jdtotal = System.currentTimeMillis() - jdstart;
         
         System.out.println("Brand X: queries=" + jodo + ", total=" + jdtotal);
      
      }
      
      System.out.println("500 rows");
      
      for ( int j=0; j<5; j++ ) {
      
         long hb = 0;
         long hbstart = System.currentTimeMillis();
         
         for ( int i=0; i<200; i++ ) {
         
            Session s = sf.openSession();
            s.setFlushMode(FlushMode.NEVER);
            Transaction t = s.beginTransaction();
            long ht = System.currentTimeMillis();

            List result2 = s.createQuery("from Foo foo where foo.id<500")
               .setReadOnly(true)
               .list();

            hb += System.currentTimeMillis() - ht;
            t.commit();
            s.close();
         
         }
         
         long hbtotal = System.currentTimeMillis() - hbstart;
         
         System.out.println("Hibernate: queries=" + hb + ", total=" + hbtotal);
   
         long jodo = 0;
         long jdstart = System.currentTimeMillis();
         
         for ( int i=0; i<200; i++ ) {
         
            PersistenceManager pm = pmf.getPersistenceManager();
            pm.currentTransaction().begin();
            long jt = System.currentTimeMillis();

            Query q = pm.newQuery(Foo.class);
            q.setFilter("id<500");
            Object result = q.execute();

            jodo += System.currentTimeMillis() - jt ;
            pm.currentTransaction().commit();
            pm.close();
         
         }
         
         long jdtotal = System.currentTimeMillis() - jdstart;
         
         System.out.println("Brand X: queries=" + jodo + ", total=" + jdtotal);
      
      }



The output:

5000 rows
Hibernate: queries=5067, total=5157
Brand X: queries=5629, total=5869
Hibernate: queries=3765, total=3825
Brand X: queries=4937, total=4957
Hibernate: queries=3746, total=3796
Brand X: queries=4807, total=4807
Hibernate: queries=3985, total=4055
Brand X: queries=4857, total=4857
Hibernate: queries=3735, total=3796
Brand X: queries=4827, total=4837
500 rows
Hibernate: queries=1722, total=1913
Brand X: queries=2413, total=2483
Hibernate: queries=1703, total=1853
Brand X: queries=2363, total=2433
Hibernate: queries=1723, total=1843
Brand X: queries=2554, total=2594
Hibernate: queries=1532, total=1682
Brand X: queries=2524, total=2584
Hibernate: queries=1552, total=1672
Brand X: queries=2524, total=2574

I am NOT going to claim that either solution is faster than the other, merely showing that performance is very comparable. If anything, HB has a small edge in this particular very oversimplified test.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 20 posts ]  Go to page 1, 2  Next

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.