Encuesta

¿Qué piensas de la adquisición de Sun por parte de Oracle?

30-06-2009 - 188 votos

Destacados Agenda

Más eventos |

Comparativa de implementaciones de JPA: Toplink, EclipseLink, Hibernate y OpenJPA

23/12/2008 16:48 xantyago1

Cansado de buscar en internet comparativas objetivas entre las diferentes implementaciones de JPA, decidí hacer pruebas yo mismo para ver el rendimiento de cada una. Dichas pruebas han dado lugar a este artículo.

Mi sorpresa ha sido que el comportamiento en lo que se refiere a requerimientos de meoria y memory leaks (al menos con la configuración por defecto) es radicalmente distinto, al menos entre las mejores (Hibernate y Toplink, en ese orden) y las peores (Eclipselink y Openjpa, también en ese orden).

En el artículo detallo, incluso con gráficos de memoria, el comportamiento de cada implementación, así como las conclusiones que, en mi humilde opinión, pueden sacarse.

Url del artículo: http://terrazadearavaca.blogspot.com/2008/12/comparativa-de-implementaciones-de-jpa.html 

Volver a actualidad

Etiquetas: j2ee, jpa, comparativa, implementaciones, hibernate, toplink, openjpa, eclipselink

Comentarios: 19

  • greeneyed 23/12/2008 18:18

    Espero que te hayas asegurado que puedes publicar comparativas de rendimiento de todas las librerias para no meterte en líos legales, ya que algunas empresas tienen la "insana" costumbre de prohibir comparativas de rendimiento de sus productos. No se si será este el caso, siendo todas implementaciones libres, pero como Oracle es una de esas empresas y TopLink está en la comparativa... ;)**

    Pero volviendo a la comparativa, está bien poder hacer esas cosas por que precisamente para eso están las especificaciones. De todas formas, hay que tener cuidado al sacar conclusiones de forma tan rotunda de unas pruebas tan limitadas y donde hay más código que el que estás comparando.

    En cuanto a detalles: las peticiones AJAX se pueden emular igual con el JMeter, al fin y al cabo son peticiones HTTP como las demás. Y que OpenJPA sea poco verborreico no se por que debe ser un problema, a mi personalmente me disgustan las librerías secundarias que en su configuración por defecto se anuncian como estrellas de cine :).

    Y no se si lo has hecho, pero lo habitual en estos casos es contactar con los equipos de los peor parados para ver si el problema que te estás encontrando es un problema resuelto (caso del memory leak) o de configuración (bajo rendimiento) y si puedes ofrecer un codigo fuente para que puedan repetir las pruebas y ver el resultado, mejor.

    ** No es coña, tengo una amiga que hizo una comparativa de implementaciones EJB2.1 y la mostró en un congreso y uno de los fabricantes la quería llevar a juicio por que quedaban mal.

  • xantyago1 23/12/2008 19:38

    Hola greeneyed, y gracias por tus consejos. Tienes razón en que obviamente a Oracle no le gustará que haya puesto por delante a Hibernate. Te respondo, en cualquier caso, a los puntos que has indicado.

    En el artículo indico que la configuración es completamente por defecto. No tendría inconveniente en pasarle el persistence.xml de cualquiera de las implementaciones de JPA al que me lo pidiera (sea cualquier lector particular o sean los propios de Oracle). Tampoco tendría inconveniente en modificar algún parámetro que me puedan indicar y repetir la prueba y, desde luego, publicar los nuevos resultados. De hecho, haciéndolo ganaríamos todos. Vamos, que si eso ocurre, consideraré que la publicación ha sido un éxito.

    Oracle, precisamente, no puede quejarse. Su comportamiento fue de los mejores, tan sólo superado ligeramente por Hibernate. Pero la comparativa los da a los dos como candidatos igual de buenos para un entorno de producción. El problema, en todo caso, creo yo, vendría de Eclipselink, el Toplink liberado para la comunidad, que fue el que peor funcionó. Lo que no sé es si Oracle mantiene ya el control de esa librería.

    Tienes razón en que hay más código que el que estoy comparando, pero no es menos cierto que entre prueba y prueba nada que no fuera la librería JPA y el persistence.xml, así que cualquier cambio en el rendimiento sólo puede ser achacable a dicho cambio.

    Sé que JMeter se puede utilizar para probar ajax, ya que son peticiones http normales, pero eso me hubiera obligado a hacer una grabación vía el proxy de JMeter, que hubiera grabado un buen montón de peticiones, algunas con parámetros de otras, que puede que JMeter no hubiera pillado bien (la llamada correlación en pruebas de prestaciones/rendimiento). Hubiera tenido que hacer limpieza, luego hubiera tenido que poner los 5 segundos de espera entre peticiónes ajax, sacando fuera del bucle la petición inicial... todo en paralelo con las llamdas a los servicios web. Como prueba hubiera sido mucho más formal, es verdad, pero mi tiempo es limitado y abrir unas cuantas ventanas de navegador con el ajax funcionando me resolvía el problema igual. Mi intención no era sobrecargar hasta que se cayera al Tomcat, tan sólo ver cómo funcionaba con unas cuantas peticiones simultáneas.

    No he contactado con los dueños de los que han funcionado peor, pero tienes razón, quizá sería buena idea. El tema será que tenga tiempo para hacerlo... y que no me dé pereza, teniendo en cuenta que Hibernate resuelve la papeleta estupendamente bien, por ahora. O, quizá, si hay que escribir alguna query demasiado cercana a Oracle, Toplink podría ser la solución.

    Por último, muy buena idea la de tu amiga. Yo trabajé con EJB 2.1 y desde luego también había diferencias entre los diferentes contenedores, aunque nunca me puse a hacer una comparativa seria. Me interesaría saber, de todas formas, si un fabricante puede, realmente, prohibir una comparativa de rendimiento en la que participe un producto suyo. Por cierto, ¿el nombre del fabricante lo puedes decir :-)?

  • Anónimo 23/12/2008 20:30

    Hola, la mayoría de fabricantes pone en sus licencias que no se pueden hacer comparativas de rendimiento de sus productos. entre estos tienes a IBM, Oracle, Microsoft, Bea (ahora de oracle). Está es su licencia de uso, que no los puedes comparar. Por eso en internet no hay muchas comparaciones de servidores de aplicaciones y tampoco de bases de datos.

  • Anónimo 24/12/2008 02:14

    muchas gracias por publicar

    jimmy

  • jmarranz 24/12/2008 09:35

    Algunas cosas:

    - Como dice greeneyed, meter Ajax, servicios web etc en una prueba en donde se trata de evaluar el rendimiento de un ORM no es buena idea, demasiadas cosas, además el consumo de memoria en Java hasta cierto punto es aleatorio, es la repetición de la misma prueba un cierto número de veces la que nos da una "verdad" más certera. Aunque entiendo que no tengas tanto tiempo para eso :)

    - Casi siempre (por no decir siempre) mayor consumo de memoria => mayor rendimiento, ambos aspectos deben ir separados en las conclusiones, aunque es verdad que en el caso de EclipseLink en ambos temas no sale bien parado según tu test.

    - Me hubiera gustado que estuviera DataNucleus (el moderno JPOX) en la comparativa, aunque sea en su encarnación JPA. La técnica de bytecode enhancement que usa juega totalmente a su favor frente a los ORM basados en reflection como son los que has testeado. Hay quien lo tiene claro aunque sin benchmark y antiguamente tenían una comparativa en donde afirmaban que JPox era claramente superior a Hibernate, imagino que la tendrían que quitar tras la llamada de algún abogado. Otra razón es porque su autor principal es un "hispano de adopción" :)

    De todas formas gracias por el "atrevimiento" de la comparativa y ahora reza porque no pasen los abogados de algunos de los implicados por tu web ;)

     

  • greeneyed 24/12/2008 13:42

    Hola,

    No es probable que te digan nada, pero no pienses que es por que salen bien parados. A los abogados esas cosas les dan igual y si en casos similares, defensa de marcas, tienen obligación de actuar igual contra todo el mundo salgan bien o mal por que en un juicio posterior pueden usar contra ellos el no haber actuado contra otros, sentando precedentes.

    Recuerdo hace unos años cuando los servidores de aplicaciones eran casi una obligación, excepto los parias de la resistencia que seguiamos con contenedores de servlets a secas, en los que se publicó una comparativa donde dos servidores salian como "Servidor de aplicaciones X" y "Servidor de aplicaciones Y". Todo el mundo intuía/sabía que eran el de Oracle y el de WebLogic, por ciertos detalles del comportamiento conocidos, pero nadie podia decirlo oficialmente. A veces sería gracioso si no fuera realidad :). En el caso de mi amiga, no recuerdo cual era pero era seguro uno de los que menciona el primer anónimo. Para esos fabricantes es práctica estándar poner esas clausulas, ya que obviamente sólo quieren que se publiquen comparativas que ellos controlen.

    Respecto a usar el navegador, al igual que el código extra que no es parte de JPA, el problema es que cuantas más variables introduces, menos exactas/generalizables son las conclusiones a las que puedes llegar. Es decir, puedes hacer esa prueba y llegar a la conclusión de que en tu sistema haciendo eso ocurre tal cosa. Pero para sacar conclusiones generales hay que estar muy preparado por que la gente que salga mal intentará encontrarle lo que sea para desvirtuarlo.

    Una opción es aportar una postura neutral tipo "oh, me ha salido esto" y dejar que las conclusiones las saque cada cual, por que los datos son los datos, pero las conclusiones si son subjetivas.

    Yo para lo del JMeter lo que hago es abrir el web con el FireBug y grabar de ahi las URL, no hago capturas de trafico por que casi me cuesta más limpiarlas que hacer las peticiones a mano, pero entiendo que si te es comodo.

    Respecto al Memory Leak, ya dices que no tienes tiempo pero en caso de curiosidad o si te pasa en algo que tengas que mirar, lo mejor es sacar dos snapshot, uno antes y otro despues de los tests, y comparar a ver que hay extra en el segundo que "no debería haber". Se encuentra uno a veces sorpresas desagradables, aunque a veces son más fáciles que otras de solucionar.

    Yo ahora mismo uso Hibernate o Toplink, aunque ultimamente tiendo a TopLink por que tiene menos dependencias, pero no he hecho ninguna comparativa en la misma aplicación.

  • Anónimo 24/12/2008 19:18

    ¿Nadie tomó en cuenta iBATIS?

  • Anónimo 24/12/2008 21:10

    > ¿Nadie tomó en cuenta iBATIS?

    Como iBatis no es una implementacion de JPA, y habla de una comparativa de JPA ? ok

  • xantyago1 26/12/2008 09:54

    Bien, he estado echando un vistazo a las famosas licencias de las librerías de implementación JPA nombradas en mi artículo. Os cuento sobre cada una de ellas por separado.

    • Toplink Essentials. Según se indica en la propia página de descarga, está licenciada bajo la COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) VERSION 1.0, que no indica nada respecto a prohibición de comparativas.
    • EclipseLink. Está licenciada bajo la Eclipse Public License Version 1.0 ("EPL") y la Eclipse Distribution License Version 1.0 (“EDL”). Tampoco he encontrado nada relativo a prohibición de comparativas.
    • Openjpa. Está licenciada bajo la Apache License Version 2.0. Vuelvo a no encontrar nada sobre la realización de comparativas.
    • Hibernate EntityManager. Viene con la GNU LESSER GENERAL PUBLIC LICENSE Version 2.1. Tres cuartos de lo mismo.

    Os ruego que si alguno ya os habéis pegado con algún tema de licencias y creéis que se me puede estar pasando algo, me indiquéis el punto concreto de alguna de ellas en el que podría entenderse algo al respecto (hasta el momento, no se ha puesto ningún abogado en contacto conmigo :-)

    Jmarranz, el tema es que esto no fue ideado inicialmente como una prueba, sino que, una vez realizado el proyecto con JPA, se trataba de elegir la implementación con la que mejor funcionara. Y hacer otro proyecto, por pequeño y simple que fuera, hubiera significado trabajoy tiempo extra, tiempo este del que no dispongo.

    Vuelvo a insistir en que la única variación entre prueba y prueba fue únicamente la librería JPA y el persistence.xml, por lo que las variaciones en el uso de memoria sólo pueden achacarse a dichas librerías.

    Y en cualquier caso, el que no se fíe siempre puede hacer pruebas él mismo, como hice yo, y publicarlas. Creo que podría apostar a que sus resultados serían muy similares.

    En cuanto a la implicación que pones "mayor consumo de memoria => mayor rendimiento", esta afirmación no sólo es discutible, sino que precisamente estas pruebas contradicen esa afirmación. Supongo que te refieres a que cuanto más guardes en memoria, más rápidamente disponible estarán los datos para la aplicación y por tanto se dispondrá de mayor rendimiento. Pero el tema es que un consumo alto o incluso excesivo de memoria (entre 2 y 3 veces más en el caso de Eclipselink y Openjpa) que además el recolector de basura no es capaz de solucionar parece más debido a memory leaks que a un intento de mejora de rendimiento. Ten en cuenta que apenas tuve 15 minutos funcionando la carga. En alguna otra prueba más larga que realicé y no publiqué, el tomcat acabó cayendo por falta de memoria en heap. Por eso indico que no son adecuados para entornos de producción.

    Aunque he oído hablar de JPOX, no se me ocurrió probarlo. De todas probé los que me parecieron los más conocidos/utilizados. Puede ser una buena idea probar DataNucleus, si dices que funciona bien.

    Greeneyed, soy de tu opinión, prefiero que me muestren datos y analizarlos yo, y si las diferencias hubieran sido sutiles, no me hubiera atrevido a sacar conclusiones tan claras. Pero es que las gráficas dejaban poco lugar a las dudas o a las interpretaciones.

    En cuanto al JMeter, te hablaba de las correlaciones. El problema en la replicación de navegaciones, ya sea con herramientas libres (como JMeter) o de pago (como LoadRunner) viene en la llamada correlación de variables, es decir, cuando lo que tienes que enviar en una petición depende de lo que haya llegado del servidor como respuesta a otra petición anterior. Esto puede llegar a complicarse mucho y es es en esto en lo que LoadRunner le da mil vueltas a JMeter (que por otro lado es una herramienta estupenda, siendo libre).  Y desde luego lo que comentas de usar el Firebug para copiar y pegar las peticiones no sirve, porque en este caso serían peticiones fijas. Tendrías que tocar luego mucho a mano para que los parámetros de una petición enviarán algo que ha llegado en la respuesta del servidor a otra anterior. En fin, no sé si me explico.

    Por último, supongo que con el snapshot te refieres a hacer un thread o memory dump, una foto, antes y después de la prueba. Pero, efectivamente, ambos dumps suelen ser crípticos y cuesta bastante, más aún sin conocer el código de las librerías, sacar algo en claro de ahí. Ya digo, es una cuestión de tiempo :-)

  • jmarranz 26/12/2008 10:53

    xantyago1:Puede ser una buena idea probar DataNucleus, si dices que funciona bien.

    Yo uso JPox para una aplicación interna y usando una base de datos Java, no puedo opinar sobre como se comporta ante alta concurrencia usando una base de datos más escalable.

    Eso sí, programar usando la API JDO es un absoluto placer, aunque te reconozco que no es la API de moda (JPA es la moda, también soportada por DataNucleus) aunque JDO tiene su guerrilla que resiste liderada heróicamente precisamente por DataNucleus :)

     

  • jmarranz 26/12/2008 11:03

    xantyago1:En cuanto a la implicación que pones "mayor consumo de memoria => mayor rendimiento", esta afirmación no sólo es discutible, sino que precisamente estas pruebas contradicen esa afirmación.

    Hombre, me refiero a si se hacen las cosas bien :)

    Te pongo un ejemplo, cualquier compilador C/C++ tiene un flag con la opción "optimizar para tamaño" y la opción "optimizar para rendimiento" y te dirán que ambas opciones a la vez no son posibles, porque una estrategia para ganar rendimiento normalmente supone gestionar valores temporales que posiblemente sean usados más tarde evitando "buscarlos" de nuevo (opción lenta).  No es un ejemplo de programación normal pero creo que se me entiende.

    Otro ejemplo más del día a día: siempre tienes la duda de si crear un objeto-utilidad en el momento en que lo necesitas o guardarlo en un atributo para la siguiente ocasión, en el primer caso como no alojas el objeto permanentemente la memoria consumida es menor (consumo medio), en el segundo caso se ocupa más memoria a costa de ganar rendimiento pues no necesitas crear dicho objeto (y su posible coste de inicialización).

     

  • xantyago1 26/12/2008 12:54

    Está claro, estoy de acuerdo contigo, jmarranz. Si las cosas se hacen bien, el uso de memoria hace que la aplicación gane en velocidad (siempre que tengas memoria disponible). Tan sólo decía que la afirmación sin explicación se quedaba coja :-) Con tu explicación queda meridianamente clara.

    Nunca he mirado en detalle JDO, y quizá sería bueno echarle un vistazo. Hay tantas cosas por mirar... Hablando de todo un poco, ¿se puede llamar a procedimientos PL con JDO? Lo pregunto porque con JPA no está del todo claro. En principio podría parecer que no tiene mucho sentido usar JPA para llamar a procedimientos almacenados, pero la verdad es que cuando sólo tienes que llamar a un PL y el resto lo puedes hacer vía JPA, agradecerías que también lo incluyera entre sus funciones. Creo que Hibernate y Toplink lo admiten con alguna extensión o así. Tengo que mirarlo.

  • Anónimo 26/12/2008 14:01

    JPA sigue siendo más lento que el caballo del malo. Cuando una aplicación tiene que dar servicio a un público masivo (venta de entradas, consultas bancarias, venta de billetes, etc.) tiene que funcionar con SQL a pelo (sobre pooles de conexiones JDBC). En estos casos, JPA no sirve porque es demasiado lento.

    Juan.

     

  • greeneyed 26/12/2008 19:27

    Por último, supongo que con el snapshot te refieres a hacer un thread o memory dump, una foto, antes y después de la prueba. Pero, efectivamente, ambos dumps suelen ser crípticos y cuesta bastante, más aún sin conocer el código de las librerías, sacar algo en claro de ahí. Ya digo, es una cuestión de tiempo :-)

    Si, para interpretarlos hace falta alguna normalmente una ayudita de alguna herramienta más sofisticada. Yo uso YourKit y aunque al principio es un poco lioso, si aprendes a usar este tipo de herramientas puedes averiguar cosas muy utiles.

    JPA sigue siendo más lento que el caballo del malo...tiene que funcionar con SQL a pelo (sobre pooles de conexiones JDBC)...

    JPA usa pools de conexiones JDBC, así que esa no es la diferencia. En todo caso, nadie discute que JPA sea lo más rápido ni que sirva para todo, así que no se a que viene el cambio de tema. Aquí se está hablando de comparar unas implementaciones de JPA con otras, no de JPA contra otras opciones. Si quieres hablar de esto último mejor abrir otro tema.

  • datanucleus 26/12/2008 21:23

    > Nunca he mirado en detalle JDO,

    JDO es una especificacion para persistencia a cualquier base de datos, no solo RDBMS. Por eso no incluyo procedimientos almacenados en la especificacion, pero DataNucleus lo permite ... con JDO o JPA. Hay mucho que no puedes hacer con JPA, que JDO permite. Y JDO va en direcciones que JPA no ha llegado a tocar, como un API para byte-code enhance, un API para definir Metadata (y por eso otra opcion a anotaciones y XML), y Savepoints, y otras cosas.

    La unica cosa con benchmarks es que deben ser publicos si tienes la intencion de publicar los resultados, porque si no ...

  • datanucleus 26/12/2008 22:01

    > JPA usa pools de conexiones JDBC,

    Correccion; JPA es una especificacion y no especifica JDBC pool. Una implementacion puede utilisar pool de conexion si quiere (y tiene todo el sentido en el mundo), pero siempre es para el usuario configurarlo bien. He visto tantas articulos en el pasado con conclusiones pero con mala configuracion de las cosas basicas(no significa que hay un error en este, pero bueno ...)

  • greeneyed 27/12/2008 13:55

    Correccion; JPA es una especificacion y no especifica JDBC pool.

    Lo sé, lo decía por analogía al caso de JDBC que decía el anónimo. 

  • Anónimo 28/12/2008 00:04

    lo decía por analogía al caso de JDBC que decía el anónimo

    El anónimo soy yo (Juan). En mi comentario he querido aclarar que aunque haya muchas implementaciones de JPA, el uso de SQL "a pelo" es lo más eficiente. Es más, cuando se esperan muchísimas conexiones, JPA no es viable y hay que utilizar SQL. Lo del pool de conexiones lo he comentado (entre paréntesis) para que quede claro que hablo de utilizar SQL sobre un pool de conexiones, no abriendo y cerrando una conexión física cada vez.

    Juan

  • greeneyed 28/12/2008 00:41

    Pues vale, Juan, y yo lo que digo es que ese es otro tema, tambien interesante, pero diferente. Y como ya ha dicho DataNucleus, lo de usar un pool o una conexion es posible en ambos casos así que no tiene nada que ver, y a eso me refería. En cuanto a eficiencia, ese es un tema muy discutido, muy hablado y bueno, si tu crees que SQL a pelo es la solución universal a todo, pues bien úsala. Algunos creemos que situaciones diferentes pueden requerir soluciones diferentes. Y si sólo crees que es la mejor para situaciones concretas por ser más eficiente, entonces no se a que viene el comentario. El artículo compara implementaciones de JPA entre si y cual es más eficiente entre ellas, punto. ¿Que todas ellas són menos eficientes que SQL a pelo en algunas situaciones? pues vale, pero ese no es el tema.

    Y repito que es un tema interesante, si quieres dar validez a tus argumentos, lo mejor es montar una comparativa de ese estilo y ver como responden las diferentes soluciones con un trafico elevado, para diferentes tipos de aplicaciones. Entonces será una discusión con fundamento.Y conste que no defiendo lo contrario ni mucho menos.

Escribe tu comentario

Sun Microsystem Logo NHT-Norwick Logo

© 2002-2007 Asociación javaHispano