viernes, 26 de diciembre de 2008

JPA implementations comparison: Hibernate, Toplink Essentials, Openjpa, Eclipselink


Summary

This article is a response to the lack of information on the net about the performance differences among the 4 most well known Java Persistence API (JPA) implementations: Toplink Essentials, EclipseLink, Hibernate and OpenJPA.
Besides results and conclusions, the full test code is also available in case you want to repeat the test yourself.
I wrote a relatively simple program which executes some queries and inserts in a MySQL database through JPA. Four fixed-time tests were done with exactly the same code, just changing the JPA implementation library and the persistence.xml. I monitored the resources used by the JVM and counted the inserts and queries executed during the tests. Finally, I show here my conclusions and also the results of these tests, so that you can draw your own. I consider the differences found among the different implementations truly relevant.
For the tests performed for this article, nothing except JPA was used. No web pages, no web or application server. Just java threads, JPA and MySQL. I give more details in the next sections.
Note: In case you are using JPA with Axis and/or the Google Web Toolkit (GWT), this other article focused on working with JPA, Axis and GWT could be of interest for you.

Description of hardware and software
The tests have been done in an Acer Extensa 5620G laptop, with a pentium Core 2 Duo T5250 Processor with 2 Gb Ram DDR2, being monitored by a standard PC.
For the tests I have used the following software:
  • Ubuntu 8.10 Intrepid Ibex
  • MySQL database, version 5.0 (installed from the official Ubuntu repositories).
  • Java Virtual Machine 1.6
  • Driver jdbc for MySQL 5.1.
  • Eclipse Ganymede
  • The employees database example for MySQL, courtesy of Patrick Crews and Giuseppe Maxia (url below in the references section)
  • JConsole for resources monitoring
  • GIMP 2 to capture screens
The database and the JVM were running in the Acer machine. But both JConsole and GIMP were executed in a PC (also equiped with Ubuntu 8.10) connected via tcp/ip to the test machine. I did it so that I did not overload the machine running the tests.
Versions of the JPA implementations tested:
  • Hibernate EntityManager and Annotations 3.4.0
  • Toplink Essentials version 2 build 41
  • Openjpa 1.2.0
  • Eclipselink 1.0.2
Description of code and tests
The code developed for the tests is available to download here. All you have to do is import the zip file in Eclipse. You will need at least one of the JPA implementation libraries. You can download them from the urls in the references section below.
The code is made up of two type of threads, one for inserting and one for querying. each of them containing a loop.
Inserting thread loop gets an arbitrary employee and makes a copy of him/her, letting MySQL generate a new emp_no. This was the only modification I did to the employees database: the emp_no is auto-generated.
Querying thread loop executes these queries in sequence:
  • A query returning the number of female employees.
  • A query returning the number of male employees.
  • A query returning all employees hired since an arbitray date.
  • A query returning all employees born after an arbitrary date.
  • A query returning all women who have earned more than an arbitrary salary.
I have also created an independent class JPAManager, which is in charge of creating the static EntityManagerFactory and the EntityManager for each of the threads. You have the details of that class in this other article focused on the problems derived from sharing EntityManager among different objects.This is the starting sequence:
  1. When the program starts, it waits 2 minutes for the monitoring infraestructure to be ready (connecting JConsole to the JVM, basically).
  2. It then starts 2 of the so-called inserting threads. I start the inserting threads before the querying threads trying that the queries do not always return the same (which will eventually happen, anyway).
  3. After starting the inserting threads, the program starts running 18 of the querying threads, inserting a pause of 10 seconds before starting next. This is so that they do not execute the same query at the same time.
  4. The program runs the threads for 30 minutes. After that time, it sends a stop signal to the threads, which will safely make them stop after the next inserting or querying round. The main program waits 15 minutes for the threads to stop and the jvm memory to stabilize.
  5. Before stopping, the threads provide information about the number of inserts/queries they have executed.
The only change from test to test was the JPA implementation library and the persistence.xml. It is important to notice that the persistence.xml was left by default for each of the implementations, omitting on purpose any kind optimization that the implementation could accept.

Before every test, the inserted records were deleted. In this way, every implementation started with the database exactly in the same situation.

Results
These were the results of the tests per JPA implementation library. Notice that the time was fixed: 30 minutes running.

Number of queries+inserts executedNumber of queries executedNumber of inserts executedMax mem occupied during the test(Mb)Mem occupied after the test(Mb)
OpenJPA3928
353039896
61
Hibernate12687
3080960713079
Toplink Essentials
5720
374019805525
Eclipselink
5874
373521395725

The maximum memory occupied is the maximum amount that the JVM reserved during the test.
The memory occupied after the test is the amount of memory that remained reserved after finishing the test.
I have emphasized the highest and lowest values for each of the columns.
You can see this graphically in the following images showing the data monitored during the different tests.

OpenJPA monitoring data

Hibernate monitoring data

Toplink Essentials monitoring data

Eclipselink monitoring data

Conclusions

My intention is that anyone can draw their own conclusions looking at the results or using the code to do a test of their own.
Nevertheless, I consider that there are a number of conclusions that one can draw watching the monitored data:
  1. There is not an implementation that clearly has the best performance. Some had a very good CPU or memory performance and some did it very well when inserting or querying. But none of them was outstanding as a whole.
  2. The number of records inserted by Hibernate was extremely higher than it was for any other implementation (4 times more compared to Eclipselink and 24 times more compared to OpenJPA). However, Hibernate was also the JPA implementation that executed the lowest number of queries, although the differences in this value (3080 for Hibernate vs 3740 for Toplink Essentials) are not so extreme as for the number of inserts.
  3. Hibernate was also the implementation that consumed more memory. But having into account that it inserted many more records than the others, it sounds reasonable.
  4. OpenJPA had the lowest value of inserts+queries.
  5. The number of inserts executed by OpenJPA was extremely low, compared to the others.
  6. The usage of CPU in the case of Toplink Essentials and Eclipselink was extremely low.
Note for the JPA implementations responsible/developers: I am aware that some optimization can be obtained by changing the persistence.xml and/or changing the code somehow. If you give me some advice on how to improve the performance of any of the implementations, I will be glad to update this post with that information.

References
Ubuntu: http://www.ubuntu.com/
Employees database: http://dev.mysql.com/doc/employee/en/employee.html, https://launchpad.net/test-db/
Openjpa: http://openjpa.apache.org/
Toplink Essentials: http://www.oracle.com/technology/products/ias/toplink/jpa/download.html
Hibernate JPA: http://www.hibernate.org/397.html
Eclipselink: http://www.eclipse.org/eclipselink/
MySQL: http://www.mysql.com/
Eclipse: http://www.eclipse.org/

Lessons learned using GWT, Axis and JPA simultaneously

Note: This article is solely focused on some issues related to the EntityManager that may appear working with GWT, Axis and JPA. If you are interested in the performance of JPA, this other post about a comparison among different JPA implementations (OpenJPA, Hibernate, OpenJPA and Eclipselink) may be of some interest for you.

In my experience with the three technologies which appear in the title of this article, I had to face a number of problems, actually quite easy to solve once you know what all is about.
So I decided to publish this, for others not to have to face these same problems.
Here you have some lessons learned that should be taken into account when working with the Google Web Toolkit, Axis and any of the JPA implementations out there.
You have this same article in Spanish here.

These are the facts:
  • EntityManager can not be shared among threads. This is specified in JPA, but you don't give it enough importance until you start using JPA from the web (which will probably be the usual case).
  • Second, Axis creates a new object (and thread) for each call to the server.
  • Third, contrary to Axis, when you use one of the so-called GWT server remote services, only one object and thread are created and this object is reused everytime the remote service is called. That is to say, GWT does not create a new object for every new call.
As a result of these facts, we have these consequences:
  • If we use a static EntityManager in a call to Axis, the code will fail as soon as two threads cross with each other (quite usual in a web application), given that they will be using the same EntityManager object.
  • Contrary to Axis, in the case of GWT it is not necessary that EntityManager is static to start generating problems; it will be enough that it is a global attribute belonging to the object that implements the GWT remote service. Being one only object that answers all petitions, two calls to the server will use the same EntityManager and this will make the code fail.
So, we can conclude two rules:
  • An Axis service must therefore create a new EntityManager and this can not be static.
  • Each method of a GWT remote service must create a new EntityManager for individual use (it is not enough that it creates it at a global level).
If any of these two rules are not followed, 2 simultaneous calls will use the same EntityManager at the same time, producing exceptions.
Unfortunately, JPA exceptions are not especially explicit. This is common to almost every implementation of JPA: they give almost no concrete information (including Hibernate).

The EntityManagerFactory can and should be shared among different threads, given that it is a quite expensive object to create.

In short, if you don't want to have problems and you would like to have a piece of code that can be used both by GWT and Axis, you could write something like this:
public class JPAManager {
private final static EntityManagerFactory emf =
Persistence.createEntityManagerFactory("JPAImplementationTest");
private EntityManager em = emf.createEntityManager();
public EntityManager getEntityManager () {
return em;
}
}
Each method called in an invocation to a web service or to a GWT server remote service should create its own JPAManager and get the EntityManager with the public method. This way you will avoid having problems among the different threads created in the invocations.

You could also use more sophisticated solutions like implementing a singleton (with the problems associated to them) or using the ServletContextListener, as someone suggested in the comments. But this simple solution worked for me and resisted some load tests.

martes, 23 de diciembre de 2008

Lecciones aprendidas en el uso simultáneo de GWT, Axis y JPA

En mi experiencia con las tres tecnologías que dan nombre al artículo, me he encontrado con algunos problemas bastante fáciles de resolver una vez sabes de qué se trata (como siempre). Por eso, y para evitar que otros se peguen con lo mismo, aquí van una serie de lecciones aprendidas que deben ser tenidas en cuenta a la hora de trabajar con el Google Web Toolkit, Axis y cualquiera de las implementaciones de JPA. Para una comparativa detallada entre diferentes implementaciones de JPA (Hibernate, Toplink, Eclipselink y Openjpa), tienes este otro artículo disponible.
Si quieres ver este artículo en inglés, lo tienes disponible aquí.

Pues bien, los hechos:
  • En primer lugar, así como el EntityManagerFactory puede ser compartido por diferentes objetos (e hilos), el EntityManager no puede ser compartido entre diferentes threads. Esto está especificado en JPA, pero no le das importancia hasta que empiezas a usar JPA desde la web (que será el caso más habitual).
  • En segundo lugar, Axis crea un nuevo objeto (e hilo) por cada petición que entra al servidor.
  • En tercero, y al contrario que con Axis, al utilizar uno de los llamados servicio remotos de servidor del GWT se crea un objeto (y thread) que es posteriormente reutilizado cada vez que se llama a dicho servicio. Es decir, no se crea uno nuevo por cada uno que entra.
Las consecuencias a las que dan lugar los hechos:
  1. Si utilizamos un objeto EntityManager estático en una llamada a Axis, el código fallará en el momento en que dos hilos se crucen (bastante normal en la web), al utilizar el mismo objeto los 2.
  2. En el caso de GWT, al contrario que en Axis, no es necesario que el EntityManager sea estático para que de problemas (que también los dará, claro); bastará con que sea un atributo global dentro del objeto que implementa el servicio remoto. Al ser un objeto único el que responde a las peticiones, 2 llamadas al servidor utilizarán el mismo EntityManager y esto hará que código falle.
  3. Un servicio de Axis deberá, por tanto, crear un nuevo EntityManager, y éste no podrá ser estático.
  4. Cada método de un servicio remoto de GWT tiene que crear un nuevo EntityManager para uso individual (no vale que lo cree el objeto a nivel global, ver punto 2. Si no lo hace, 2 llamadas simultáneas al mismo servicio remoto utilizarán a la vez el mismo EntityManager, dando inmediatamente lugar a excepciones.
Por desgracia, las excepciones de JPA son muy poco explícitas. Esto es común para casi todas las implementaciones de JPA: dan poca información concreta de errores (incluyendo a Hibernate).

El EntityManagerFactory sí puede ser compartido por los diferentes hilos.

En definitiva, si no queréis tener problemas y queréis usar un código que puedan utilizar tanto GWT como las llamadas a servicios web a través de Axis, podríais usar un código como el siguiente:

public class JPAManager {
private final static EntityManagerFactory emf =
Persistence.createEntityManagerFactory("JPAImplementationTest");
private EntityManager em = emf.createEntityManager();
public EntityManager getEntityManager () {
return em;
}
}

Cada método llamado en la invocación del web service o del servicio remoto de servidor de GWT deberá crear su propio JPAManager. De esta forma, os evitáis tener problemas entre los diferentes hilos creados en las invocaciones.

Se pueden usar métodos más sofisticados, como implementar un singleton o usar el ServletContextListener, como ha puesto alguno en los comentarios. Pero lo cierto es que este sencillo método funcionó y resistió algunas pruebas de carga.

lunes, 22 de diciembre de 2008

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

Este artículo es una respuesta a la falta de información existente en internet en lo que se refiere a las diferencias entre las 4 implementaciones más conocidas de la llamada Java Persistence API (JPA de ahora en adelante).
He realizado 4 pruebas exactamente iguales, una con cada implementación de JPA. Las diferencias entre las diferentes implementaciones han sido muy considerables, dando como ganador indiscutible a Hibernate, y como perdedor a Eclipselink. Puedes leer las conclusiones detalladas más abajo, si quieres.

También tenéis disponible este otro artículo acerca del uso de GWT, Axis y JPA de manera simultánea, porque tiene sus particularidades y merece la pena dedicarle uno completo. El actual, en cambio, se referirá exclusivamente a las diferencias en rendimiento detectadas en las diferentes implementaciones más utilizadas de JPA: Toplink, EclipseLink, Hibernate y OpenJPA.

Descripción del proyecto y las pruebas

El servidor con que se han hecho las pruebas (un Tomcat 5.5) ha ejecutado de manera concurrente dos proyectos desarrollados con Eclipse consistentes en lo siguiente:
  • Un proyecto que no tiene pantallas y sí acceso a base de datos (Oracle), tanto de inserción como de búsqueda. Utiliza JPA para el acceso a bbdd y Axis para la exposición de un web service. 
  • Un proyecto que sí tiene pantallas. Utiliza igualmente JPA para acceder a Oracle  (sólo búsqueda) y el Google Web Toolkit para la parte cliente (GWT de ahora en adelante), haciendo uso intensivo de ajax.
Para lanzar carga se ha utilizado:
  • JMeter para el servicio web, configurado con 5 hilos que lanzan 100 peticiones cada uno. Se configuró un tiempo de subida de 30 segundos. En total, por tanto, 500 llamadas , habiendo siempre 5 simultáneas.
  • Google Chrome para hacer peticiones, abriendo 10 ventanas simultáneas. Hay que tener en cuenta que cada ventana dispone de varias peticiones Ajax de actualización que se ejecutan cada 5 segundos (se ha forzado un tiempo tan corto la prueba). Es decir, cada 5 segundos se ejecutan 10x3=30 peticiones ajax simultáneas. No he utilizado JMeter para lanzar la carga web debido a que no hubiera replicado la parte ajax de la página, que es lo que realmente introduce carga en el servidor.
  • Para la medición de la memoria, he utilizado el JConsole, incluido en el jdk 1.6.
  • Para el mínimo tratamiento de imágenes (cortar, fundamentalmente) he utilizado el GIMP 2.
La prueba da comienzo con el Tomcat recién arrancado. Seguidamente se abren las 10 ventanas del navegador. Después se espera un minuto aproximadamente, para posteriormente lanzar los 5 hilos con JMeter, que lanzarán las 500 peticiones. Al acabar las peticiones se dejan pasar unos 5 minutos y después se activa a mano el Garbage Collector desde Jconsole. Esto último se hace para no tener que esperar (cuestión logística, no tengo tanto tiempo :-).

Diferencias en el rendimiento

Pues bien, éste ha sido el comportamiento de las diferentes implementaciones, de peor a mejor.

Eclipselink

Eclipselink parece ser la siguiente versión de Toplink, que Oracle habría donado a la comunidad de Eclipse. Hay que tener en cuenta que Toplink lleva mucho tiempo funcionando, no como implementación JPA, sino como capa de acceso a dato. Oracle añadió capas para que fuera accesible vía JPA, exactamente igual que hicieron los de Hibernate.
Supongo, por tanto, que Eclipselink es aún una implementación muy nueva que aún tiene que madurar, exactamente igual que Openjpa.

Eclipselink dio el peor rendimiento durante las pruebas, con mucha diferencia. La memoria ocupada no hizo más que aumentar desde el principio de la prueba, poniendo de manifiesto que hay algún tipo de memory leak sin controlar en dicha implementación.
En concreto, el máximo de memoria utilizada (60 mb) triplica al utilizado por Hibernate o Toplink (poco más de 20 mb).

La memoria ocupada al final de la prueba, aun después de forzado el recolector de basura (GC), quedó en 43 mb, marcando también un record máximo, y casi triplicando la ocupada por Hibernate o Toplink (13 y 15 mb respectivamente).

Los tiempos de respuesta, por otro lado, fueron el doble que los de Hibernate o Toplink.

Apache Openjpa

Openjpa es la respuesta de Apache en lo que se refiere a JPA, y es la implementación por defecto en Gerónimo, el servidor de aplicaciones de Apache que incluye JPA y EJB3. En cualquier caso, me sorprende que la gente de Apache haya liberado algo tan aparentemente inmaduro.

Openjpa se comportó algo mejor que Eclipselink, sobre todo en lo que se refiere a los memory leaks, pero no tanto como para considerarla una alternativa viable para su uso en producción.
Por un lado, se observa el típico comportamiento de diente de sierra del Garbage Collector a lo largo de la prueba (aunque no de manera tan correcta como en Hibernate o Toplink), y por otro lado la memoria ocupada en el heap al final de la prueba es menor que la implementación que mostró peor rendimiento (32 mb frente a los 43 mb de Eclipselink), pero el doble que en el caso de Hibernate o Toplink.
Otro dato a tener en cuenta sobre Openjpa es que no informa en el log del servidor cuando arranca, al contrario que todas las demás implementaciones. Esto al menos ocurre con la configuración por defecto.

Toplink Essentials

Toplink Essentials es un subconjunto gratuito del software java de acceso a datos de Oracle. Dicha empresa le añadió varias capas de abstracción para hacerlo compatible con JPA, pero la base continúa siendo la original, estando por tanto bastante maduro.

El comportamiento de Toplink se acerca mucho al de Hibernate. La diferencia en memoria ocupada es poco apreciable. Por un lado, el máximo a lo largo de la prueba fueron unos 25 mb, al igual que Hibernate, y el total ocupado al finalizar fue de 15 mb, 2 megas por encima de Hibernate. Si tenemos en cuenta la enorme diferencia con Eclipselink y Openjpa, podemos decir que el rendimiento es muy similar al de Hibernate, y es desde luego una alternativa viable para su uso en producción.

Hibernate

Hibernate es probablemente el ORM más utilizado, el que más influencia tuvo en la especificación de EJB3, y la implementación de JPA que viene incluida en las últimas versiones de JBoss. La gente de Hibernate, al igual que la de Oracle, incluyó varias capas de abstracción en su software para hacerlo compatible con JPA. Lo bueno es que el software que hay detrás de esas capas está sobradamente probado, al haber muchísima gente que lo utiliza ya en entornos de produccción, lo que lo hace bastante maduro. Esto, entiendo yo, explicaría el excepcional rendimiento que dio durante la prueba.

El rendimiento en Hibernate fue muy superior al de sus competidores, a excepción de Toplink. Hibernate necesitó 3 veces menos de cantidad de memoria para funcionar que Eclipselink y Openjpa, y al terminar la prueba estaba ocupando 3 veces menos también que dichas implementaciones.
Aunque su rendimiento se asemeja al de Toplink, lo supera en memoria ocupada al final de la prueba (13 mb de Hibernate frente a 15 de Toplink).
El diente de sierra debido al funcionamiento del recolector de basura es perfectamente apreciable en la imagen, pero funciona ligeramente mejor que para Toplink cuando se deja de lanzar carga. Toplink queda con unos 24 mb ocupados, frente a los 20 de Hibernate. Lo cierto es que cuando se fuerza la ejecución del garbage collector, la diferencia entre ambos se reduce a 2 mb. Según la carga que vaya a recibir una aplicación, esa diferencia podría llegar a ser importante.

Conclusiones
  • El ganador de esta competición de implementaciones de JPA es, sin lugar a dudas, Hibernate. Fue la implementación que mejor resultado dio en cuanto a consumo de memoria durante y después de la prueba y en cuanto a tiempos de respuesta. Toplink le sigue muy de cerca en rendimiento.
  • En cuanto al perdedor, Eclipselink tuvo el peor comportamiento de todos, seguido muy de cerca por Openjpa. En mi humilde opinión, ninguna de las 2 implementaciones parece lo suficientemente madura como para ser utilizada en producción, al menos con la configuración por defecto. El consumo de memoria sin freno y los aparentes memory leaks llevarán a dejar colgado al servidor de aplicaciones cuando se ocupe toda la memoria heap disponible.
  • Mi recomendación, hoy por hoy, por madurez y seguridad en el rendimiento, es sin duda para Hibernate, teniendo en cuenta que las pruebas se han hecho con Toplink Essentials, un subconjunto de la implementación de JPA de Oracle, que si se quiere completa hay que pagar por ella. Hibernate, en cambio, es completamente libre y gratuita.

lunes, 24 de noviembre de 2008

Fotos en Panoramio, Google Maps y Earth


Bueno , pues por fin he conseguido que me publiquen los de Panoramio (que son españoles, por cierto) un par de fotos en en los mapas de google. Podéis ver y la , en Portugal. La primera es de La Casona del Peregrino, en Cantabria, cerca de Terán. La segunda es de la Casa Grande en Portugal, en el Algarve, en un pueblecito llamado Burgau. También se puede acceder a la lista en Panoramio aquí.

Desgraciadamente, ambas fotos se ven muy pequeñas. Esto es debido a la falta actual de popularidad respecto a las otras que hay desde hace tiempo. Digamos que es la misma idea que Google: a más pagerank, apareces más arriba en la lista de resultados. Aquí se traduce en la cantidad de zoom que tienes que aplicar para que se vea la foto. Las más populares (en las que más se ha pinchado) necesitan poco zoom. Las menos populares requieren mucho más zoom
para aparecer.

Bueno, aparte de haber cumplido una promesa hecha a Sally, de la "Casa Grande" en Burgau, he aprendido cómo va esto de las fotos en los mapas de google, que siempre está bien.

miércoles, 3 de septiembre de 2008

Google Chrome: GMail y Blogger no funcionan (solucionado)

Bien, acabo de instalar Google Chrome en mi máquina del trabajo, un XP que accede vía proxy autenticado a internet. No sé si tendrá que ver con esto, pero lo cierto es que no funcionan ni GMail ni el acceso a Blogger como propietario de un blog. El resto de páginas (y eso incluye GMaps) funcionan de forma correcta. En el caso de GMail, basta con poner https://gmail.google.com o http://gmail.google.com. La pantalla que se obtiene es ésta, como veis, vacía:


En el caso de Blogger, estando en tu blog sin autenticar, basta con que le des arriba a "Acceder", la pantalla que se obtiene es ésta:


Insisto, no sé si será el acceso por proxy. Un compañero ha dicho que ayer lo instaló en casa y GMail le funcionaba.
En cualquier caso, me parece asombroso que 2 de las aplicaciones más importantes de Google no funcionen en su propio navegador, sea o no debido al proxy.

¿Le pasará alguien más? ¿Tenéis alguna solución?

Solución:

Bueno, pues encontré aquí la respuesta. Parece, efectivamente, que Chrome tiene problemas con los proxys autenticados. En el caso de que el proxy sea el ISA de Microsoft, basta con instalar el Microsoft Firewall Client. De esta forma, ya funcionan tanto GMail como el acceso autenticado a Blogger.

jueves, 14 de agosto de 2008

Gasol y la foto

Quizá hayáis visto en los periódicos que Los Angeles Times y algunos medios británicos han criticado a Gasol por la foto haciendo el gesto de rasgarse los ojos a lo chino. Pues bien, he buscado el sitio (que, por cierto, es un blog) en Los Angeles Times. Lo tenéis aquí: crítica a Gasol en Los Angeles Times.

Sobre el artículo no tengo mucho que decir, aparte de que me parece que parte de la premisa errónea (al menos en España) de que el gesto es racista. Para mí dicho gesto no es de burla ni despectivo ni racista, sino simplemente un gesto que pretendía ser de simpatía/cercanía hacia los chinos (creo que así fue concebido el anuncio) y por tanto considero que el blogger hace el juicio basándose en su propio concepto del gesto. Dicho concepto no coincide con el mío y creo que tampoco con el de muchos españoles (no creo que sea el único). Tampoco con el de la embajada china en España: El anuncio de la selección de baloncesto, ni racista ni ofensivo (El País).
En cuanto a la frase "Let the Spanish act racist in the privacy of their own little country", me parece que esa frase sí es despectiva con España y con los españoles, aparte de transmitir soberbia y desprecio (¿racismo?) hacia un país y sus habitantes.

El caso es que mucho más interesante que el artículo es el debate que se crea después, en el que, en general, nos ponen a parir a los españoles.

Hay 2 comentarios, en cambio, con los que me he sentido plenamente identificado, sobre todo con uno, que es el que cito aquí abajo. El otro es justo el siguiente (que ya no pego aquí), escrito por un americano-asiático que no considera que la foto sea ofensiva.

Posted by: Kush Lalwani | August 13, 2008 at 01:06 PM

"Let the Spanish act racist in the privacy of their own little country."
With this commentary the writer just proves what his article is worth. There's something you should do ALWAYS you feel like judging someone: get all the information.

Just an example:

The word "mulato/a", in Spanish, is applied to someone who is half white/half black. Its use in Spain is stricly "descriptive" and seldom derogatory. As a matter of fact, it can be used in a possitive way.

In Cuba (where half the population or more has some Sub-Saharian-African ancestor), the word mulata has even more possitive connotations. It's even a compliment, a flirting cliche. It's a charming word which quite often implies appreciation or love.

For some time, I'm told, the word "mulato" has been used in some parts of the US the same way as "nigg€r" or "negr0"; that is, with an offensive intention.

Now if an American "mulato" (not pointing at anyone, it is just that it fits this particular example) comes and tell me that I cannot go to Cuba and call a cuban girl "mulata" because in his country (a third party who has no bussiness in this two-sided "game") it is considered racist, then he DOES HAVE A REAL PROBLEM understanding how his place in the World works.

From the point of view of a Spaniard, the only way to see "Racism" in this photo is to have a race-based mindset at first. It is said that the ones claiming "racism!" are too often the very first ones to be racist.

Peace.

martes, 8 de julio de 2008

Música para todos

Hace poco conocí lilypond y mutopía.

Lilypond es un programa al estilo LaTex para escribir partituras. La idea es que tú escribes en el código que acepta lilypond y luego se lo das al programa para que lo exporte, por ejemplo, a pdf. Ni que decir tiene que lilypond es gratuito y de código abierto.
Un ejemplo de una escala en do mayor en código lilypond:

{
c' e' g' e'
}

La cosa se puede llegar a complicar mucho.

Mutopía, por otro lado es un proyecto para poner a disposición de todo el mundo partituras en formato lilypond (.ly) y, ya que estamos, por qué no, en pdf. En este caso, la idea es que tú, que tienes la partitura comprada, la pasas al formato lilypond, luego ejecutas el programa para generar el pdf y finalmente subecódigo fuente y el pdf (así como algún otro formato que ellos han establecido) al servidor del proyecto.

Éste es un ejemplo de una partitura que he tocado y conozco. Por lo que he visto, está clavada a la que tengo yo.


La lista de autores es muy considerable, estando destinada a música clásica, fundamentalmente: Beethoven, Mozart, Bach...

Desde luego, si te gusta la música y el mundo del código abierto, merece la pena echarle un vistazo.

domingo, 6 de julio de 2008

Un par de vídeos de Kenia




Pongo aquí un par de vídeos de nuestra estancia en Kenia. Se trata de una leona con sus crías, por un lado, y de un viaje en mini bus por una carretera terrorífica keniana por otro. Los he subido también a YouTube. Podéis ver aquí el de los leones y aquí el del viaje.
Los accidentes de tráfico son una de las principales causas de mortalidad en Kenia (es la novena causa en el mundo). Unas 3.000 personas mueren al año en Kenia debido a esta lacra.

video

video

viernes, 4 de julio de 2008

Street View ya en Francia: el tour

Google ya ha añadido la funcionalidad Street View en Francia. Se han estrenado con el recorrido del tour.
Se nota perfectamente que han utilizado el software de reconocimiento facial para difuminar los rostros.
A ver cuándo empieza a verse Madrid con esta herramienta (en la que puede que aparezca yo mismo, según cuento en este post).

Edificio de Bull en Google Earth

Pues ya está visible el edificio de Bull de Madrid en Google Earth. Es el de la izquierda. El de la derecha es el de Genesis.
Ambos edificios son de los primeros del Campo de las Naciones.
Lo cierto es que se ve bien desde lejos. Cuando te acercas, la cosa pierde, sobre todo porque se ve el edificio de la imagen de satélite debajo. Esto último también pasa con las torres Kio y, en general, con cualquier edificio "pegado" de esta forma.
En cualquier caso, no deja de estar curioso.

jueves, 3 de julio de 2008

Salí en la foto de Google

Actualización: La zona donde vivo ya está visible en el Street Viewer.  Y, efectivamente, salí en la/s foto/s. Éste soy yo.

Ayer me encontré con uno de los coches de Google que están recorriendo Madrid fotografiándolo para Street View. Era un Opel negro, con el mástil y la cámara panorámica arriba, exactamente igual que éste.

Me lo encontré exactamente en esta rotonda, en la Avenida del Talgo.


View Larger Map

El menda iba con chaqueta y corbata. Uno de muchos pringaos con funda de portátil al hombro. El coche llegó a la rotonda, dio la vuelta y volvió a subir. ¿Estaba haciendo fotos en ese momento? No lo sé. Lo cierto es que si las estaba haciendo, he salido en unas cuantas, todas las que hizo mientras llegaba a la rotonda, hacía el giro y volvía para arriba.
Lo cierto es que iba bastante rápido, aunque, como es sabido, la resolución de las fotos de Street Viewer ha bajado una barbaridad, debido a las múltiples quejas (e incluso demandas) que han recibido los de Google por temas de privacidad.
Es una lástima, por cierto, porque ahora la calidad es pésima (comparada con la había al principio).
Igualmente, están difuminando las caras. De hecho, están usando un software de reconomiento de patrones faciales para hacerlo.

En fin, que Madrid pasará a formar parte de las ciudades europeas que estarán disponibles para darte un garbeo a pie de calle sin salir de casa. ¿Cuánto tardarán en publicarlas? Cuando salgan, veré si estoy por ahí, je, je.

Desde la terraza

Bueno, pues ésta es la primera entrada de este blog, que pretende ser un sitio donde contar historias, detalles, cosas que me interesan. ¿Ejemplos? Tecnología, música (tocarla y oírla), sexo, simuladores de vuelo, cine, animales.
No es casualidad que la tecnología vaya por delante. La tecnología, la música y el sexo han guiado mi vida, así que se merecen ese primer lugar.
Este blog, por cierto, ha sido creado gracias a Flock, que acabo de instalar en Ubuntu y lo cierto es que me ha hecho plantearme ya en serio la creación de un blog. ¿Razones? La comodidad a la hora de postear y lo integrado que está todo lo que tiene que ver con la web social: del.icio.us, GMail, rss, blogs, youtube...

Un último detalle. ¿Por qué la terraza de Aravaca? Lo de la terraza tiene un doble significado:

1.- Es un sitio desde el que mirar lo que pasa desde arriba. Y por "desde arriba" me refiero a un sentido literal, físico y otro figurativo. En cuanto al literal, soy un fanático de los aviones y de los simuladores de vuelo. Mi aplicación de referencia, aparte del navegador, es el Google Earth. En cuanto al significado figurativo, éste es un sitio en el que comentar las cosas que pasan, lo que me llama la atención, desde lo que oigo por la radio hasta lo que me ocurrió ayer por la mañana en plena calle, que contaré en otro post.
En cuanto a Aravaca, el sitio donde me acuesto y me levanto está situado en esta zona de los madriles.

2.- La terraza es un sitio en el que conversar tomando algo. Bueno, conversar, opinar, emocionarse, discutir incluso... Exactamente lo mismo que un blog :-)

Lo dicho. Ahí va el primero, y espero que no sea el último.