Y el claro ganador es C

Ya no seguí con mis comparaciones entre C y Java porque, de verdad, he andado demasiado ocupado, con cosas académicas, de trabajo y personales. Pero hoy por fin terminé de escribir las pruebas unitarias para las estructuras de datos que estamos viendo en mi curso de ídem, y como la última que hemos visto fueron árboles rojinegros, decidí echarle un ojo a mis pruebas.

Para los que no lo sepan, los árboles rojinegros son árboles binarios autobalanceados, lo que en su caso particular quiere decir que un camino simple (sin regresarse nunca) de cualquier nodo a cualquiera de sus hojas siempre tiene el mismo número de nodos negros. Eso se traduce (por una propiedad de los árboles rojinegros que dice que un nodo rojo siempre tiene dos hijos negros) a que la diferencia más grande de longitudes entre ramas es que una tenga k nodos, y la otra 2k (una rama con puros nodos negros, otra con negro, rojo, negro, rojo, etc.) La estructura permite agregar y eliminar elementos con complejidad en tiempo acotada por la altura del árbol; que siempre esté balanceado garantiza que dicha complejidad es siempre O(log n). Los árboles rojinegros son una estructura de datos utilizada en todos lados por (como veremos ahorita) su espectacular desempeño; en particular, el kernel de Linux incluye una implementación desde mi punto de vista preciosa y humilladoramente elegante; la pueden checar en /usr/src/linux/lib/rbtree.c.

No voy a poner mi código para agregar o eliminar elementos a árboles rojinegros; no sólo porque mis alumnos aún no entregan su práctica, sino además porque es demasiado engorroso. No es ciencia de cohetes, pero sí hay suficientes casos como para que uno tenga que ir haciendo dibujitos en papel para no perderse en qué punto del algoritmo nos hayamos. Como sea, terminé de escribir el código en Java y C como siempre, y corrí unas pruebas con un millón de elementos (me pueden pedir el código, si quieren).

Ambas implementaciones le ganan por mucho a MergeSort; me imagino que algo tendrá que ver el uso de memoria (MergeSort crea el equivalente a log n listas con n elementos cada una durante la ejecución del algoritmo, mientras que los árboles rojinegros usan O(1) de memoria al agregar). Ambas son básicamente idénticas, incluyendo que usan recursión en el paso interesante: es recursión de cola, por lo que sencillamente lo pude haber reescrito iterativamente; pero como les digo el algoritmo ya es lo suficientemente engorroso como para que lo complicara aún más con un acumulador. La única diferencia discernible en el uso de cada versión, es que guardo la raíz cada vez que agrego en un elemento en C; tengo que hacerlo para no tener que andarla persiguiendo cada vez. En Java, al usar el diseño orientado a objetos, siempre tengo una variable de clase para la raíz.

Con Java, el algoritmo tarda 0.777676317 segundos (en promedio) en agregar 1,000,000 (un millón) de elementos. C sin optimizaciones tarda 0.376824469 segundos; con optimizaciones tarda 0.183850452 segundos. Por supuesto ambas versiones son genéricas; la de Java propiamente usando genéricos, la de C usando void* como tipo de dato, y pasando una apuntador a función para hacer comparaciones. Con 10,000,000 (diez millones) de elementos la diferencia es todavía más abismal; Java tarda 20.266719661 segundos, mientras que la versión en C tarda 1.881134884 segundos; pero esto ya no me extraña, dado que como ya había visto la última vez, con 10,000,000 de elementos, Java no puede evitar no utilizar el swap.

No me queda claro por qué C gana; dado que MergeSort también es recursiva, y ahí Java le ganaba a C, hubiera esperado que en el caso de los árboles rojinegros pasara lo mismo. Lo que sí es que el desempeño de la estructura de datos es espectacular, y a mí me parece de las estructuras más bonitas y poderosas que existen. Por supuesto los diccionarios (¿alguien sabe una mejor traducción para hash table?) también son muy padres; pero siempre está el hecho de que en el peor de los casos el buscar y el eliminar tardan O(n). Y como mis experimentos con QuickSort me recordaron hace unas semanas, el peor caso (o uno suficientemente malo) siempre anda asomándose detrás de las esquinas.

Imprimir entrada Imprimir entrada

Más sobre carreritas entre Java y C

Total que Omar me pidió mi código para hacer él mismo pruebas, lo que me obligó a limpiarlo un poquito. Entre las cosas que hice al limpiar mi código, fue cambiar cómo llenaba los arreglos y listas; originalmente los estaba llenando así (en Java):

import java.util.Random;
// ...
    Random r = new Random();
    // ...
    int n = r.nextInt() % 100;

Y así en C:

#include <stdlib.h>
// ...
    srand((unsigned int)time(NULL));
    // ...
    int n = rand() % 100;

El cambio que hice fue el reemplazar el número mágico 100 con N en el módulo al generador de números pseudo aleatorios, donde N es el número de elementos. Esto cambió radicalmente los resultados; para ponerlo en perspectiva, aquí están los resultados en C de una corrida (suelen ser todos muy similares) con módulo 100 (incluí el qsort de glibc a sugerencia de otro lector):

Tiempo QuickSort (normal): 46.125371409 segundos
Tiempo QuickSort (int): 6.318009789 segundos
Tiempo QuickSort (memcpy): 29.476040174 segundos
Tiempo QuickSort (long): 4.455134060 segundos
Tiempo QuickSort (glibc qsort): 0.182938334 segundos
Tiempo MergeSort (lista): 5.097989382 segundos
Tiempo MergeSort (dlista): 3.018067951 segundos

En Java los números son:

Tiempo QuickSort (int): 2.231362337 segundos
Tiempo QuickSort (genéricos): 35.452854731 segundos
Tiempo MergeSort: 2.599635738 segundos

Haciendo módulo N, los resultados son, en C:

Tiempo QuickSort (normal): 0.558278904 segundos
Tiempo QuickSort (int): 0.117254171 segundos
Tiempo QuickSort (memcpy): 0.279380050 segundos
Tiempo QuickSort (long): 0.121708671 segundos
Tiempo QuickSort (glibc qsort): 0.220501083 segundos
Tiempo MergeSort (lista): 5.311177622 segundos
Tiempo MergeSort (dlista): 3.196143267 segundos

Y en Java:

Tiempo QuickSort (int): 0.172914364 segundos
Tiempo QuickSort (genéricos): 0.578500354 segundos
Tiempo MergeSort: 2.15927644 segundos

Al inicio me súper saqué de onda, pero no tardé en encontrar la respuesta. Si N=1000000 (un millón), y cada entero en mi arreglo está entre 0 y 99 (inclusive), eso quiere decir que en promedio cada elemento del arreglo está repetido 10,000 veces, lo que hace que la probabilidad de encontrar un pivote malo (el mínimo o máximo del arreglo) sea mucho mayor que si estuvieran mejor distribuidos los valores. Es por ello que cuando cambio a hacer módulo N, todas mis versiones del algoritmo mejoran, algunas por varios órdenes de magnitud; en general el pivote es un buen pivote. Esta no es toda la historia, por supuesto; de ser así sólo tendría que elegir un pivote aleatorio y todo funcionaría más rápido, y como expliqué en la entrada anterior, en mis pruebas usar un pivote aleatorio no mejora sustancialmente el desempeño del algoritmo. Me parece que teniendo tantos elementos y tan poquitos valores (comparativamente) para inicializarlos, sencillamente ocurre muchas veces que un subarreglo tiene muchos elementos iguales, y entonces incluso un pivote aleatorio tiene mucha probabilidad de ser el mínimo o el máximo.

Sin embargo, esto no parece molestarle a qsort de glibc; es endiabladamente rápido. Incluso en mi versión módulo 100 corre en menos de medio segundo, y de hecho es la única implementación del algoritmo que lo hace. Como le comentaba al lector que me recomendó probar con qsort, la complejidad del mismo es más de un orden de magnitud mayor que mis versiones: qsort son unas 250 líneas de código no muy fácil de leer a comparación de 22 líneas en cada una de mis versiones. La complejidad radica en primer lugar en cómo encuentra el pivote: selecciona la mediana entre el primer, medio y último elementos del subarreglo (ordenándolos de paso); y en segundo lugar en que no hace recursión: utilizando una pilita se ahorra el estar gastando registros de activación, y mete todo dentro de un while.

No sé si sea eso lo que lo hace el ganador indiscutible de las distintas implementaciones; lo que sí sé es que glibc lo comenzaron a escribir a inicios de los ochentas, y que en estos treinta años le han metido todas las optimizaciones que se les han podido ocurrir. De cualquier forma, estoy ahora más contento con mis implementaciones en C: si el arreglo tiene sus valores bien distribuidos, cada una de mis versiones en C le gana a su equivalente en Java, y de hecho mi mejor versión genérica en C (que tiene exactamente la misma firma de qsort, por cierto) es sólo 0.05 segundos más lenta. Que no está nada mal, si me permiten decirlo.

De cualquier forma, los arreglos con muchos elementos repetidos son una entrada válida de QuickSort, así que Java sigue siendo bastante bueno en su versión para enteros (por cierto, mi versión genérica era desde el inicio mejor que la de Java; lo que pasa es que en Java el módulo incluye valores negativos, y entonces Java tenía el doble de valores distintos que la versión de C), y no terriblemente lento en comparación en las otras versiones. Para cosas genéricas C le puede ganar fácilmente; pero usando enteros nada más, Java le gana de calle a mi versión en C para arreglos con muchos elementos repetidos. Y de hecho implementando una versión iterativa de QuickSort, no dudo que Java le diera una buena pelea a qsort (un torito, para el que quiera animarse).

La otra conclusión importante es ver la enorme diferencia que puede significar el tipo de entrada para QuickSort; es por eso que Java utiliza MergeSort en general en sus algoritmos de ordenamientos. Es más lento en el mejor caso de ambos, sin duda; pero siempre es O(n log n). Además es estable (no cambia el orden de dos elementos iguales), lo que también está padre.

Dado que ya limpié el código gracias a Omar, lo pueden bajar de aquí. Dado que son implementaciones de una estructura y dos algoritmos que probablemente sean los más conocidos en el mundo, ni siquiera le pongo licencia a los archivos.

Imprimir entrada Imprimir entrada

Carreritas entre Java y C

Estoy enseñando Introducción a Ciencias de la Computación II (mejor conocida como ICC-2) por primera vez en mi vida, en gran medida por un ligero error administrativo. La verdad es que me estoy divirtiendo como enano (al parecer, tristemente disfruto yo más el curso que mis alumnos), y entre las cosas divertidas que decidí hacer fue el darle a mis alumnos la oportunidad de hacer las prácticas en C (en lugar de Java) por un punto extra durante el curso, o medio si hacen al menos la mitad. Desafortunadamente, ninguno de mis alumnos me ha entregado una práctica escrita en C.

Como sea, para poder dejarles las prácticas en C a mis alumnos, primero tengo que hacerlas yo, y eso es en gran medida la razón de que me esté divirtiendo tanto. Por supuesto también hago las prácticas en Java; como ICC-2 es en gran parte estructuras de datos, esto también significa ver las características novedosas de Java, como son iteradores y genéricos. Lo cual también es muy divertido; especialmente cuando puedo comparar los dos lenguajes en cosas como velocidad de ejecución.

Como es necesario siempre que uno ve arreglos y listas, les dejé a mis estudiantes que programaran QuickSort y MergeSort. Yo recuerdo que como estudiante tuve que programar esos algoritmos al menos tres veces: la primera en ICC-2, la segunda en Análisis de Algoritmos, y ahora sí que como dice la canción, la tercera por placer. También recuerdo claramente que QuickSort me parecía el mejor de ambos algoritmos; la inocencia de tener veinte años, supongo.

Total que implementé ambos algoritmos en C y en Java, y me llevé una sorpresa con los resultados. Voy a relatar lo que resultó de investigar porqué las diferencias en velocidades, que la verdad yo no termino de entender.

Aquí está QuickSort en Java:

public static void swap(T[] a, int i, int j) {
    if (i == j)
        return;
    T t = a[j];
    a[j] = a[i];
    a[i] = t;
}

public static < T extends Comparable < T > >
                 void quickSort(T[] a) {
    quickSort(a, 0, a.length-1);
}

private static < T extends Comparable < T > >;
                  void quickSort(T[] a, int ini, int fin) {
    if (fin - ini < 1)
        return;
    int i = ini + 1, j = fin;
    while (i < j)
        if (a[i].compareTo(a[ini]) > 0 &&
            a[j].compareTo(a[ini]) < = 0)
            swap(a, i++, j--);
	else if (a[i].compareTo(a[ini]) <= 0)
	    i++;
	else
	    j--;
    if (a[i].compareTo(a[ini]) > 0)
        i--;
    swap(a, ini, i);
    quickSort(a, ini, i-1);
    quickSort(a, i+1, fin);
}

Y aquí está en C:

inline static void
swap(void** a, int i, int j)
{
	if (i == j)
		return;
	void* t = a[i];
	a[i] = a[j];
	a[j] = t;
}

void
quicksort(void** a, int n, func_compara f)
{
	quicksort_aux(a, 0, n-1, f);
}

static void
quicksort_aux(void** a, int ini, int fin, func_compara f) {
	if (fin - ini < 1)
	    return;
	int i = ini + 1, j = fin;
	while (i < j)
		if (f(a[i], a[ini]) > 0 &&
                    f(a[j], a[ini]) < = 0)
			swap(a, i++, j--);
		else if (f(a[i], a[ini]) <= 0)
			i++;
		else
			j--;
	if (f(a[i], a[ini]) > 0)
		i--;
	swap(a, ini, i);
	quicksort_aux(a, ini, i-1, f);
	quicksort_aux(a, i+1, fin, f);
}

(En mi blog el código aparece bonito con destacamiento de sintaxis; no sé cómo aparecerá en RSS, pero dudo que bonito.)

Con el código así, la versión en Java necesita 33.4 segundos (en promedio en mi máquina) para ordenar un arreglo de un millón (1,000,000) de elementos aleatorios. Sin optimizaciones, la versión en C tarda 114.7 segundos; lo cual es una diferencia brutal, si me permiten decirlo. Con la mejor optimización (-O3; el resultado es idéntico a -Ofast), esta velocidad baja a 44.85 segundos; mucho mejor, pero de cualquier forma más lento que con Java.

La versión en C utiliza void** como tipo del arreglo, y recibe un apuntador a función f justamente para emular los genéricos de Java; la idea es que el QuickSort de C pueda ordenar arreglos de cualquier tipo de elemento. Nada más por completez, incluyo la definición del tipo func_compara, así como la implementación usada para estas pruebas:

typedef int  (*func_compara)      (const void*   a,
				   const void*   b);

int
compara_enteros(const void* a, const void* b) 
{
	int aa = *((int*)a);
	int bb = *((int*)b);
	return aa - bb;
}

Mi primera impresión fue que estos “genéricos” en C (altamente basados en la biblioteca GLib) le estaban dando en la madre a la velocidad de ejecución de mi implementación en C. El andar siguiendo los apuntadores, sacar el valor de las referencias en compara_enteros, y los castings probablemente eran la razón (pensaba yo) de que mi versión en C fuera (ligeramente) más lenta que la de Java. Así que hice trampa y volví a implementar QuickSort, pero esta vez nada más para enteros:

inline static void
swap_int(int* a, int i, int j)
{
	if (i == j)
		return;
	int t = a[i];
	a[i] = a[j];
	a[j] = t;
}

void
quicksort_int(int* a, int n)
{
	quicksort_int_aux(a, 0, n-1);
}

static void
quicksort_int_aux(int* a, int ini, int fin) {
	if (fin - ini < 1)
	    return;
	int i = ini + 1, j = fin;
	while (i < j)
		if (a[i] > a[ini] &&
                    a[j] < = a[ini])
			swap_int(a, i++, j--);
		else if (a[i] <= a[ini])
			i++;
		else
			j--;
	if (a[i] > a[ini])
		i--;
	swap_int(a, ini, i);
	quicksort_int_aux(a, ini, i-1);
	quicksort_int_aux(a, i+1, fin);
}

No muy sorprendentemente, esta versión le partió completamente su madre a la de Java: tarda en promedio 6.35 segundos. Hago notar que los elementos del arreglo son generados aleatoriamente; por lo que el escoger un pivote aleatorio entre ini y fin no serviría (en teoría) de nada. Ciertamente no marcó ninguna diferencia en mis pruebas.

Aunque esta versión es bastante rápida, estaba haciéndo muchísima trampa. De nada (o muy poco) me sirve un QuickSort rapidísimo, si voy a tener que reimplementarlo cada vez que cambie el tipo de mis arreglos. Así que me puse a pensar cómo mejorar una versión “genérica” en C. La respuesta es que sí se puede, pero es bastante feo desde mi punto de vista.

La idea es sencillamente utilizar aritmética de apuntadores, y al intercambiar elementos el copiarlos usando la memoria:

inline static void
swap_memcpy(void* a, int i, int j, size_t s, void* t)
{
	if (i == j)
		return;
	memcpy(t, a+(i * s), s);
	memcpy(a+(i * s), a+(j * s), s);
	memcpy(a+(j * s), t, s);
}

void
quicksort_memcpy(void* a, int n, size_t s, func_compara f)
{
	void* t = malloc(s);
	quicksort_memcpy_aux(a, 0, n-1, f, s, t);
	free(t);
}

static void
quicksort_memcpy_aux(void* a, int ini, int fin,
                    func_compara f, size_t s, void* t) {
	if (fin - ini < 1)
	    return;
	int i = ini + 1, j = fin;
	while (i < j)
		if (f(a+(i*s), a+(ini*s)) > 0 &&
                    f(a+(j*s), a+(ini*s)) < = 0)
			swap_memcpy(a, i++, j--, s, t);
		else if (f(a+(i*s), a+(ini*s)) <= 0)
			i++;
		else
			j--;
	if (f(a+(i*s), a+(ini*s)) > 0)
		i--;
	swap_memcpy(a, ini, i, s, t);
	quicksort_memcpy_aux(a, ini, i-1, f, s, t);
	quicksort_memcpy_aux(a, i+1, fin, f, s, t);
}

Esta versión es superior a la de void** ya que puedo pasarle un arreglo de tipo int* directamente, y funciona sin problema; la versión void** necesita por fuerza que le pase un arreglo de apuntadores al tipo que me interesa; en otras palabras, tengo que pasarle un int**, y además tengo que hacerle cast a void**. Además de esto (que no es poco), es más rápido que la primera versión en C, y más rápido que la versión en Java. No por mucho, pero más rápido: tarda 27.5 segundos con un millón de elementos.

Por lo demás, está bastante fea; necesito por fuerza el tamaño del tipo que me interesa ordenar (porque el arreglo lo veo como un chorizo enorme de bytes), y por lo mismo para intercambiar elementos del arreglo debo utilizar memcpy, además de que cargo por todas partes un pedazo de memoria t para guardar el valor temporal durante el intercambio; la alternativa hubiera sido usar variables globales (the horror!), o solicitar y liberar memoria en cada intercambio de variables.

Hasta aquí estaba más o menos satisfecho: ya tenía una versión “genérica” en C que era más rápida que la de Java (aunque desde mi punto de vista la solución sea bastante fea), pero entonces se me ocurrió que estaba siendo muy injusto: si hice una versión tramposa para C (la que sólo sirve para enteros), debería hacer una versión tramposa para Java también. Así que eso hice:

public static void swap(int[] a, int i, int j) {
    if (i == j)
        return;
    int t = a[j];
    a[j] = a[i];
    a[i] = t;
}

public static void quickSort(int[] a) {
    quickSort(a, 0, a.length-1);
}

private static void quickSort(int[] a, int ini, int fin) {
    if (fin - ini < 1)
        return;
    int i = ini + 1, j = fin;
    while (i < j)
        if (a[i] > a[ini] &&
            a[j] < = a[ini])
            swap(a, i++, j--);
        else if (a[i] <= a[ini])
            i++;
        else
            j--;
    if (a[i] > a[ini])
        i--;
    swap(a, ini, i);
    quickSort(a, ini, i-1);
    quickSort(a, i+1, fin);
}

Esta versión tarda 2.26 segundos en ordenar un arreglo de un millón de elementos, lo que la hace casi tres veces más rápida que la versión tramposa de C. ¿Por qué ocurre esto? Sinceramente, no tengo idea; lo único que se me ocurre es que con 1,000,000 recursiones, el compilador Just-In-Time (JIT) de Java alcanza a optimizar algo durante la ejecución del programa que la versión en C no puede. Yo no veo otra alterantiva; pero me encantaría oír teorías.

Sólo un pequeño dato para terminar con QuickSort; hice otra versión tramposa en C para el tipo long, y ésta corre en 4.35 segundos, lo que la sigue haciendo más lenta que la de Java, pero más rápida que la de enteros (int) en C. ¿A lo mejor porque mi máquina es arquitectura AMD64? Una vez más, no tengo idea; pero sí me gustaría saber qué carajo hace la JVM para ser tan rápida.

Los enigmas no terminaron ahí, porque también implementé MergeSort en Java y C. Primero les enseño mis estructuras de datos en ambos lenguajes; estas son mis listas en Java:

public class Lista< T > implements Iterable< T > {
    protected class Nodo< T > {
	public T elemento;
	public Nodo< T > siguiente;
	public Nodo< T > anterior;
    }
    protected Nodo< T > cabeza;
    protected Nodo< T > rabo;
    public void agregaFinal(T elemento) { ... }
    public void agregaInicio(T elemento) { ... }
    ...
}

Ignoren el Iterable; es sólo para poder recorrer la lista con el foreach de Java. Las listas en C siguen el modelo estructurado en lugar del orientado objetos; por lo tanto en C lidiamos con los nodos directamente (mientras en Java siempre están ocultos al usuario):

struct lista 
{
	void* elemento;
	struct lista* siguiente;
	struct lista* anterior;
};

struct lista* lista_agrega_final  (struct lista* lista,
				   void*         elemento);
struct lista* lista_agrega_inicio (struct lista* lista,
				   void*         elemento);

Por su puesto para su práctica mis alumnos tuvieron que implementar más cosas; pero nada de eso es relevante para lo que discuto aquí. Mi implementación de MergeSort en Java (para estas listas) fue la siguiente:

private static < T extends Comparable< T >> Lista< T >
    merge(Lista< T > li, Lista< T > ld) {
    Lista< T > l = new Lista< T >();
    Lista< T >.Nodo< T > nli = li.cabeza;
    Lista< T >.Nodo< T > nld = ld.cabeza;
    while (nli != null && nld != null) {
        if (nli.elemento.compareTo(nld.elemento) < 0) {
            l.agregaFinal(nli.elemento);
            nli = nli.siguiente;
        } else {
            l.agregaFinal(nld.elemento);
            nld = nld.siguiente;
        }
    }
    while (nli != null) {
        l.agregaFinal(nli.elemento);
        nli = nli.siguiente;
    }
    while (nld != null) {
        l.agregaFinal(nld.elemento);
        nld = nld.siguiente;
    }
    return l;
}

public static < T extends Comparable< T >> Lista< T >
    mergeSort(Lista< T > l) {
    int n = l.longitud();
    if (n == 1)
        return l;
    Lista< T > li = new Lista< T >();
    Lista< T > ld = new Lista< T >();
    int i = 0;
    Iterator< T > iterador = l.iterator();
    while (i++ < n/2)
        li.agregaFinal(iterador.next());
    while (i++ <= n)
        ld.agregaFinal(iterador.next());
	
    li = mergeSort(li);
    ld = mergeSort(ld);
    return merge(li, ld);
}

La versión en C es la que sigue:

static struct lista*
merge(struct lista* li, struct lista* ld, func_compara f) 
{
	struct lista* l = NULL;
	struct lista* ii = li;
	struct lista* id = ld;

	while (ii != NULL && id != NULL) {
		if (f(ii->elemento, id->elemento) < 0) {
			l = lista_agrega_inicio(l, ii->elemento);
			ii = ii->siguiente;
		} else {
			l = lista_agrega_inicio(l, id->elemento);
			id = id->siguiente;
		}
	}
	while (ii != NULL) {
		l = lista_agrega_inicio(l, ii->elemento);
		ii = ii->siguiente;
	}
	while (id != NULL) {
		l = lista_agrega_inicio(l, id->elemento);
		id = id->siguiente;
	}

	struct lista* tmp = lista_reversa(l);
	lista_libera(l);
	return tmp;
}

struct lista*
mergesort(struct lista* l, func_compara f)
{
	int n = lista_longitud(l);
	if (n == 1) {
		struct lista* uno =
                        lista_agrega_inicio(NULL, l->elemento);
		return uno;
	}
	struct lista* li = NULL;
	struct lista* ld = NULL;
	int i = 0;
	struct lista* tmp = l;
	while (i++ < n/2) {
		li = lista_agrega_inicio(li, tmp->elemento);
		tmp = tmp->siguiente;
	}
	while (i++ < = n) {
		ld = lista_agrega_inicio(ld, tmp->elemento);
		tmp = tmp->siguiente;
	}

	tmp = lista_reversa(li);
	lista_libera(li);
	li = tmp;

	tmp = lista_reversa(ld);
	lista_libera(ld);
	ld = tmp;

	tmp = ordenamientos_mergesort(li, f);
	lista_libera(li);
	li = tmp;

	tmp = ordenamientos_mergesort(ld, f);
	lista_libera(ld);
	ld = tmp;

	tmp = merge(li, ld, f);
	lista_libera(li);
	lista_libera(ld);
	return tmp;
}

Dado que una "lista" es realmente un nodo de la lista (siguiendo el modelo utilizado por GLib), no tengo guardado en nigún lado el rabo de la lista; por eso agrego elementos al inicio, y cuando termino la volteo. Hice mis pruebas de nuevo con 1,000,000 elementos, y lo primero que me sorprendió fue que fuera tan rápido en comparación con QuickSort; yo recordaba que cuando los implementé en mi carrera, la diferencia no era tanta. A lo mejor ahora programo mejor.

La versión en Java tarda (en promedio) 2.25 segundos; la versión en C 4.8, más del doble. Esta vez ya estaba preparado y no me sorprendió tanto, y de inmediato pensé que una obvia optimización es cargar el rabo de cada lista, y así poder agregar elementos al final en tiempo constante, sin tener que preocuparme de voltearla después. Para eso creé esta estructura de datos:

struct dlista {
	struct lista* cabeza;
	struct lista* rabo;
	int longitud;
};
void dlista_agrega_final(struct dlista* dl, void* elemento);
void dlista_agrega_inicio(struct dlista* dl, void* elemento);

Pude entonces simplificar mi versión de MergeSort:

static struct dlista*
merge(struct dlista* dli, struct dlista* dld, func_compara f) 
{
	struct dlista* dl = dlista_nueva();
	struct lista* ii = dli->cabeza;
	struct lista* id = dld->cabeza;

	while (ii != NULL && id != NULL) {
		if (f(ii->elemento, id->elemento) < 0) {
			dlista_agrega_final(dl, ii->elemento);
			ii = ii->siguiente;
		} else {
			dlista_agrega_final(dl, id->elemento);
			id = id->siguiente;
		}
	}
	while (ii != NULL) {
		dlista_agrega_final(dl, ii->elemento);
		ii = ii->siguiente;
	}
	while (id != NULL) {
		dlista_agrega_final(dl, id->elemento);
		id = id->siguiente;
	}

	return dl;
}

struct dlista*
mergesort(struct dlista* dl, func_compara f)
{
	int n = dl->longitud;
	if (n == 1) {
		struct dlista* uno = dlista_nueva();
		dlista_agrega_final(uno, dl->cabeza->elemento);
		return uno;
	}
	struct dlista* dli = dlista_nueva();
	struct dlista* dld = dlista_nueva();
	int i = 0;
	struct lista* tmp = dl->cabeza;
	while (i++ < n/2) {
		dlista_agrega_final(dli, tmp->elemento);
		tmp = tmp->siguiente;
	}
	while (i++ < = n) {
		dlista_agrega_final(dld, tmp->elemento);
		tmp = tmp->siguiente;
	}

	struct dlista* tmp2;
	tmp2 = mergesort(dli, f);
	dlista_libera(dli);
	dli = tmp2;

	tmp2 = mergesort(dld, f);
	dlista_libera(dld);
	dld = tmp2;

	tmp2 = merge(dli, dld, f);
	dlista_libera(dli);
	dlista_libera(dld);
	return tmp2;
}

Esta nueva versión corre en 2.72 segundos; mucho más cerca a la versión de Java, pero todavía más lenta. Lo único extra que se me ocurrió que podía hacer era eliminar el manejo de memoria; pensando que tal vez Java es más rápido (en este caso) porque puede diferir el liberar memoria hasta después de correr el algoritmo. Así que quité las llamadas a la función dlista_libera tratando de emular como sería tener recolector de basura, y por supuesto el algoritmo corrió ahora más lento: 2.92 segundos. ¿A lo mejor con 1,000,000 de elementos consigo forzar que Linux pase memoria al swap? No tengo idea; pero la verdad lo dugo: tengo 4 Gb de memoria, y no vi que el foquito de mi disco duro se prendiera.

Todos estos resultados pueden atribuirse a errores del programador (dícese, yo), pero honestamente no creo estar haciendo nada obviamente mal. Mi teoría favorita (y de hecho la única) es que el compilador JIT de la JVM está haciendo algo de magia que el simple ensamblador optimizado de C no puede; lo cual sería una muesta feaciente e innegable de las ventajas que pueden tener los lenguajes de programación que compilan para una máquina virtual altamente optimizada. Sumado a que es mucho más sencillo programar todas estas estructuras de datos si uno no tiene que preocuparse de manejar la memoria, y además con la fuerte (y desde mi punto de vista muy bonita) tipificación de datos que ofrecen los genéricos en Java, la verdad no vería por qué alguien escogería C sobre Java para programar cosas que tengan que repetir una misma tarea cientos de miles de veces.

Por supuesto es un experimento sólo en mi máquina, y en estos días 1,000,000 de elementos me suena a que ya no es realmente tanto. Con 10,000,000 de elementos, la versión en C tardó 36.32 segundos, y la versión en Java tardó 41.98 segundos; además de que tuve que aumentarle el tamaño al heap de la máquina virtual de Java a 4 Gb. Si lo aumentaba a 2 Gb, tardaba 54.99 segundos; en ambos casos el foquito de mi disco duro se prendió. En uso de memoria, sin duda C sigue siendo mucho superior (al costo de que uno tiene que andar manejándola a mano).

De cualquier forma, es impresionante lo rápido que es Java hoy en día; cuando yo lo comencé a aprender (el siglo pasado), todavía muchísima gente se quejaba de lo lento que era. Ahora yo (que no tengo poca experiencia programando) no puedo hacer que una versión en C del mismo algoritmo le gane.

En nuestras vidas profesionales lo más probable es que mis alumnos y yo no tengamos que implementar ninguno de estos algoritmos nunca; lo más seguro es que ya existirá una versión suficientemente buena y suficientemente optimizada disponible, lo que haría medio inútil que la implementáramos de nuevo. Sin embargo, me parece importante que un computólogo las implemente aunque sea una vez en su vida, y entienda cómo funcionan y cómo podrían utilizar una versión personalizada para algún obscuro problema que se encuentren.

Y ahora tengo que trabajar en mis algoritmos para árboles binarios.

Imprimir entrada Imprimir entrada

Diaspora

Hace (literalmente) años oí por primera vez de Diaspora, un simulador de vuelo espacial basado en Battlestar Galactica, una de mis series de ciencia ficción favorita. La idea del juego sonaba bien, pero la verdad no le di mucho crédito; hay siempre decenas de proyectos para juegos, y la mayor parte no pasan de ser más que buenas intenciones, o en el mejor de los casos mods de otros juegos. Un buen ejemplo de esto es Parsec, un juego del que oí por primera vez (y esto es en serio) el siglo pasado, y que en 2001 básicamente se murió. En 2003 liberaron el código fuente, y en febrero de este año parecía que volvería a levantar, pero al final ya no supe nada. Probablemente nunca llegue a nada.

Por suerte no ocurrió lo mismo con Diaspora: hace unos días anunciaron que la primera parte del juego estaba lista; pueden ver el trailer en el tubo. Hoy (después de que llegáramos madreadísimos de La Paz) lo instalé, y me sorprendió el profesionalismo con el que está hecho, incluyendo una completa actuación de voz. Lo único malo es que no tengo mi joystick (la verdad, ni siquiera sé si aún funciona), y el ratón no es el mejor modo de jugar este tipo de cosas.

Diaspora

Diaspora

Échenle un ojo; hay binarios para Linux, Windows y Mac OS X, y aunque el juego trae sólo unas cuantas misiones, también incluye un editor para crearlas, así que es diversión garantizada para toda la familia.

Imprimir entrada Imprimir entrada

La Paz

Cuando tenía 17 años, mi hermano, un amigo y yo tratamos de irnos a Real de Catorce a comer peyote. Eso no ocurrió, así que nos fuimos a La Paz, y de ahí a Constitución, donde una tía mía vive. Fue un viaje memorable por varias razones, y la primera vez que visité La Paz, aunque sólo unas horas de paso hacia Constitución, y un día de paso en el regreso a la Ciudad de México.

Hotel La Concha

Hotel La Concha

A los 24 años, mis cuates de la carrera y yo hicimos un “viaje de titulación” (aunque ninguno de nosotros se había titulado en ese momento) a La Paz. Estuvimos ahí diez días (más los casi cuatro necesarios para ir y volver: 18 horas de camión más 18 horas de ferry de Mazatlán a La Paz). También fue un viaje memorable, y uno de los viajes que con más cariño recuerdo.

Playa Balandra

Playa Balandra

A mis 35 años me encuentro de nuevo en La Paz, porque Edgar se nos casa aquí el sábado. Ayer Isabel y yo volamos a San José del Cabo, rentamos un carro, y de ahí manejé los 200 kilómetros a La Paz, en uno de los recorridos en carretera más divertidos que he tenido en mi vida (es altamente satisfactorio frenar con motor justo antes de entrar a una curva a 150 Km/h).

Gaviota

Gaviota

Después de asentarnos en nuestro hotel, fuimos a cenar riquísimo a un restaurante sobre el malecón, y después fuimos a un antro repleto de veinteañeras (atraídas por la barra libre para chavas), y de cuarentones libidinosos (atraídos por las veinteañeras).

El Hongo

El Hongo

Hoy fuimos a Playa Balandra, y después a comer a El Tecolote. En la noche habrá un coctel previo a la boda, y mañana es la ceremonia en sí. El domingo Isabel y yo manejamos de regreso a San José del Cabo, y volamos de regreso a la Ciudad de México.

Espíritu Santo

Espíritu Santo

Acaba de llover por aquí (cosa no muy común; no llovía hacía tres años), y todo está verde y exuberante de vida. Hace once años que vinimos era lo opuesto: estaba seco y no se veía nada moverse; pero ahora el cielo está lleno de aves, y por una razón extraña hay cientos de mariposas amarillas por todos lados. Estoy todo el tiempo esperando encontrarme con Mauricio Babilonia.

No creo escribir más entradas en el blog mientras esté aquí; pero estoy actualizando todo el tiempo mi perfil en Google Plus; es mucho más cómodo subir fotos al momento por ahí, y además durante el día la verdad yo no noto la diferencia entre mi cámara digital, y la incluida en mi teléfono.

Imprimir entrada Imprimir entrada

Fight them until we can’t

Al final de la segunda temporada de Battlestar Galactica, los colonos llevan un año viviendo en un planeta horrible, pero que los esconde de los Cylons por estar dentro de una nébula. O algo así. Todos al parecer son miserables bajo la presidencia de Gaius Baltar, includo Gaius Baltar.

Entonces por supuesto aparecen los Cylons, pero esta vez no desean exterminar a la raza humana; ahora sólo quieren oprimirnos. O algo así; el punto es que básicamente ocupan el asentamiento humano en Nueva Caprica. Mientras ven desfilar a los centuriones, el Jefe Galen Tyrol le pregunta a Starbuck: What do you want to do now, Captain?

Y Starbuck responde: The same thing we always do. Fight them until we can’t.

La respuesta es la única sensata; la alternativa es cruzarse de brazos y decir “nos chingaron, pues ya ni modo”. La escena me vino a la mente la noche de las elecciones, y de nuevo cuando el TEPJF dictaminó como ya sabíamos que iba a dictaminar, desechando todas las evidencias presentadas, y negándose a dar más tiempo a presentar aún más. Sería irrisorio, si no fuera tan trágico.

El fraude que ocurrió el primero de julio fue mucho más descarado que el de hace seis años; todos vieron (si querían ver) la compra de votos como política de partido, el derroche en gastos de campaña por parte del PRI, y la total parcialidad de Televisa. Fue el PRI de mi niñez, de 1982, de 1988; como hombre maduro ahora veo repetirse las prácticas que yo soñaba mis hijos jamás tendrían que ver. Era lo único bueno que parecía haber resultado de que Fox hubiera ganado (él sí legítimamente) las elecciones de hace doce años. Y el papel de Televisa (y medios afines) es todavía peor (y más preocupante); Televisa antes hacía lo que el gobierno en turno le dijera. Ahora impone diputados, senadores, y al parecer “presidentes”.

El sexenio ilegal e ilegítimo de Felipe Calderón se gestó con un fraude y comenzó con una resistencia enorme a su imposición. El resultado fue uno de los peores sexenios de los que tengamos historia; literalmente decenas de miles de muertos, con la delincuencia organizada más fuerte que nunca (y probablemente coludida con personajes a todos los niveles del gobierno), un desempleo y pobreza galopantes, y consecuentemente una violencia que comienza a afectar incluso a la Ciudad de México, que durante estos años se convirtió en uno de los pocos lugares donde las cosas no estaban tan mal.

El sexenio de este pobre y patético títere telenovelesco, si acaso empieza, lo hará en condiciones peores y con una resistencia mucho más fuerte, mucho más organizada, y que afortunadamente ha decidido colectivamente, en general, permanecer pacífica. Yo a regañadientes me sumo a la idea de que cualquier resistencia que demos debe seguir siendo pacífica, porque la perspectiva de que mis hijos nazcan en un país donde, después de un escándalo como el de los documentos proporcionados por The Guardian, que en cualquier otro país hubiera resultado en comités de senadores para investigar y en al menos una o dos cabezas políticas rodando, aquí no pasa absolutamente nada, sí me hace cuestionarme si de verdad no será ya necesario recurrir a la violencia como medio legítimo de resistencia.

Pero al fin y al cabo comprendo que en caso de que estalle la violencia, los que más van a morir y sufrir van a ser (de nuevo, como siempre) los más jodidos. Sólo por eso también me sumo a la idea colectiva de que resistamos pacíficamente; pero voy a comprender (y no necesariamente condenar) si no todo mundo lo hace.

(A todo esto, ¿dónde están las masas alegres de gente que votó por el PRI? Se supone lo hicieron casi 20 millones, ¿no? ¿Dónde están, colmando las plazas y las calles celebrando su “triunfo”?)

El sexenio que acaba ha sido de las peores cosas que le han pasado a México; además de lo que ya comenté, la educación pública (que es la única de calidad en este país), la investigación científica, la promoción y desarrollo de cultura, y los servicios de salud se han ido todos al carajo. Las condiciones de los trabajadores en el país se han deteriorado a grados inaceptables, y sus derechos se han visto atacados y mermados en todos los frentes. Los casos de todos los mineros muertos, Luz y Fuerza y Mexicana de Aviación son sólo unos cuantos.

El sexenio que viene (si empieza) va a ser peor. Van a tratar de ir por todo; la privatización de Pemex, la venta de la CFE (que al fin y al cabo tiene el sindicato más inútil de la historia), la SEP en control absoluto de Elba Esther Gordillo, y por lo tanto un empeoramiento de la educación pública a nivel básico y medio, y el uso de las secciones charras SNTE como arma política. No lo duden que también tratarán de cortar los presupuestos de la UNAM y el resto de las universidades públicas, e incluso tal vez “sugieran” que deberían empezar a cobrar cuotas. Y por supuesto, el ataque continuo a la Ciudad de México, cortándole su presupuesto aunque siga siendo de las entidades que más dinero produce en el país.

Las cosas están muy mal en el país desde hace varios años; se pueden poner mucho peor.

¿Qué vamos a hacer nosotros? Lo mismo que hemos hecho siempre: pelear hasta que ya no podamos.

De nosotros (de todos nosotros) depende que las cosas no se pongan mucho peor. No basta ir a estudiar/trabajar y cumplir con nuestras obligaciones (aunque ciertamente, es el mínimo que se puede esperar de cualquiera); tenemos todos que integrarnos a la vida política. No se vale nada más estarse quejando de los pinches políticos y de los pinches partidos, y esperar que mágicamente esos pinches políticos y esos pinches partidos generen de forma espontánea una clase política a nuestro gusto.

Tenemos todos como ciudadanos que ponerlos a raya; salir a las calles (de forma pacífica) y mostrarles que no estamos dispuestos a aceptar ciertas cosas. Fueron marchas y manifestaciones las que consiguieron el alto al fuego unilateral contra el EZLN en 1994; fueron marchas y manifestaciones las que lograron que pudiéramos elegir nuestros gobernantes en la Ciudad de México en 1997; fueron marchas, manifestaciones, y una huelga larguísima y desgastante, las que evitaron que se impusieran las cuotas en la UNAM; fueron marchas y manifestaciones las que impidieron el desafuero del Peje.

Salir a las calles funciona. Y podemos aumentar la intensidad de la resistencia, sin tener que recurrir a la violencia; como lo hicieron este fin de semana los chavos de #YoSoy132 tomando casetas en autopistas. Se puede organizar una huelga general que involucre trabajadores de varios ramos, y estudiantes de universidades. Se pueden hacer muchas cosas.

Pero tenemos que entrarle todos. Debemos seguir peleando.

Hasta que ya no podamos.

Imprimir entrada Imprimir entrada

Dead Space

Hace casi tres meses que no comento acerca de mis platinos en el PlayStation 3. Estaba enclaustrado escribiendo la tesis, y por ello es que no había escrito al respecto; pero estar enclaustrado no evitó que jugara en mi PS3. De hecho, era básicamente el único entretenimiento que tuve (como deben haber leído, no fui al cine mucho en estos meses). El último platino que había platicado fue el de Need for Speed: SHIFT; el siguiente que obtuve fue el de Dead Space, en abril.

Dead Space

Dead Space

Dead Space fue otro juego que compré usado en California, después de leer en todos lados que era “aterrador”. Como yo no juego First Person Shooters (FPSs) en el PS3, ninguno de los juegos que había jugado en él habían sido de terror; Red Dead Redemption: Undead Nightmare involucra zombies, pero la verdad es más de risa que de terror; y Uncharted: Drake’s Fortune tiene al final cosas que les podría quedar la definición de zombies, pero nunca es realmente de terror.

Dead Space es un juego aterrador. Uno interpreta a Isaac Clarke (un fabuloso homenaje a Isaac Asimov y Arthur C. Clarke), un ingeniero en ruta al USG Ishimura, un “rompe planetas” (literalmente planet cracker en inglés, y no hay mejor definición para lo que hace), junto con un pequeño equipo de rescate. El Ishimura no responde, y lo último que se sabe de él es un mensaje donde pedían ayuda. Isaac está particularmente interesado en ir porque su novia (o ex novia; tenían “cosas que discutir”) se encuentra en la nave.

Todo sale mal desde el inicio; la nave en que llegan al Ishimura se estrella en su puerto espacial, e inmediatamente son atacados por (¿cómo adivinaron?) zombies, que son simpáticamente llamados “necromorfos” en el juego. En la escaramuza mueren todos excepto el líder, una experta en comunicaciones, e Isaac, que queda separado de ellos, e inmediatamente después la nave en que llegaron explota, dejándolos atrapados en el moribundo Ishimura.

A partir de ese momento Isaac se dedica a pelear con los aterradores necromorfos, que además suelen aparecer detrás de cada esquina y ducto de ventilación, mientras hace esfuerzos heroicos por mantener al Ishimura funcionando lo suficiente como para que él y sus compañeros sobrevivan, y recibiendo ayuda (e intrigas) a través de la radio por parte de los otros dos sobrevivientes, que también terminan separándose. Isaac no es soldado; es un ingeniero, y utiliza herramientas de construcción como armas la mayor parte del tiempo. Además, tiene un “traje de ingeniero” que es básicamente la cosa más maravillosa del universo; funciona a la vez como armadura, traje espacial, centro de comunicación (el traje proyecta un holograma, y así es como funcionan los menúes del juego), y además tiene botas gravitacionales para cuando se encuentra en espacios carentes de gravedad.

El juego entonces es en general estar recorriendo pasillos oscuros llenos de cadáveres, esperando con terror que un necromorfo aparezca de repente, mientras una música maravillosamente tétrica le pone a uno los pelos de punta, y que explota de repente en dramáticos violines (piensen Psycho) cuando por fin le brincan a uno los mostros. Cuando uno no anda vagando pasillos, generalmente es porque la acción ocurre en enormes escenarios con gravedad zero, donde uno tiene que utilizar estratégicamente la habilidad de Isaac de saltar de pared a piso (o techo) con sus botas gravitacionales, generalmente mientras lo persiguen necromorfos.

La historia es bastante entretenida, siendo a la vez un homenaje y una parodia de todas las películas de ciencia ficción de terror habidas y por haber en el universo, y uno realmente no se entera de qué está pasando (qué pasó con el Ishimura, qué causa que los cadáveres se vuelvan necromorfos, dónde está la novia de Isaac), hasta casi el final del juego. El modo de juego es el común para Third Person Shooters (TPSs), con la entretenida novedad de que uno puede generar un “campo de estasis” que causa que los enemigos se muevan en cámara lenta. Es endiabladamente divertido.

No es particularmente difícil el trofeo de platino, pero yo me tardé porque al inicio el juego me espantaba tanto que no podía jugar más de un capítulo por día, y muchas veces ni siquiera eso; nada más veía una “estación de guardar”, guardaba mi juego y me iba a dormir soñando con necromorfos persiguiéndome. Cerca de la mitad del juego (cuando ya había mejorado mi traje y mis “armas”), agarré mejor ritmo y a partir de entonces fui mucho más rápido. Una vez terminado el juego, como suele ser cuando uno quiere un trofeo de platino, tuve que volverlo a jugar en la dificultad más perra, y eso me llevó algo más de tiempo.

Acabé encantado con el juego, al grado de que habiendo obtenido el trofeo de platino, estuve a punto de comprar en la PSN mejores armas y trajes para volver a jugarlo. Al final decidí que no (el traje que uno recibe por terminar el juego es bastante chido), pero eso no quita que ha sido uno de los juegos que más me ha entretenido en mi PS3. Y además consiguió lo que yo quería: de verdad tenerme espantado. Los malditos necromorfos son aterradores.

Todo mundo dice que el trofeo de platino de Dead Space 2 es de los más difíciles que existen: para obtenerlo, hay que jugar el juego en la segunda dificultad más perra, y sólo se puede salvar tres veces a lo largo de todo el juego. No me importa; quiero jugarlo (y sacar el platino), y al parecer dentro de poco será el mejor momento para comprarlo, porque Dead Space 3 está a punto de salir.

Si pueden, juéguenlo; es altamente recomendable. Sólo si son como yo, no se quejen de estar chillando como niña de seis años en algunas partes.

Imprimir entrada Imprimir entrada

El Caballero de la Noche Asciende

Hace casi dos semanas (el domingo no pasado, sino el anterior), fuimos a ver The Dark Knight Rises, después de haber fallado los dos primeros intentos de ir a verla. No había escrito al respecto por estar ocupado.

Se aplican las de siempre.

The Dark Knight Rises

The Dark Knight Rises

Hace más de treinta años salió la primera película “moderna” de Superman, con Christopher Reeve en el papel del hombre de acero. La primera secuela fue incluso mejor (podemos discutirlo), y de ahí pa’l real no ha vuelto a haber una buena pelícua del kriptoniano.

Once años después de la primera película de Superman, Batman de Tim Burton sería la siguiente muestra decente de adaptar al cine a un superhéroe; la elección de Michael Keaton como Bruce Wayne se puede cuestionar, pero Jack Nicholson fue fabuloso haciéndola de Jack Nicholson actuando como el Joker. La secuela de esta película puede considerarse también como un triunfo (aunque tal vez menor), y una vez más a partir de la tercera todo empezó a irse al carajo.

Con la llegada del nuevo milenio Marvel por fin empezó a ordenar sus cosas, y sacó X-Men en el año 2000, lo que sería el comienzo de su innegable supremacía actual en las adaptaciones de cómics a la pantalla grande, que culminó este año con el estreno de Avengers. DC mientras tanto en general ha seguido metiendo la pata hasta la ingle, con películas malas de plano como Green Lantern, o nada más aburridas como el idiota intento de continuar las películas de Superman de Christopher Reeve.

Después de ver Avengers este año, yo creí que sería la cima a la cual llegarían las adaptaciones de cómics al cine durante mucho tiempo. No esperaba que pudiera ser superada sólo unas semanas después, y menos por DC, con la única franquicia que han podido mantener de forma decente.

The Dark Knight Rises, con todas sus fallas (los descarados hoyos en la trama, que se toma ridículamente en serio, y lo inverosímil de la historia), es una extraordinaria adaptación de los mitos del Caballero de la Noche, y un final perfecto para la triología. No sólo eso; consigue darle a Bruce Wayne un final feliz, cosa que en general no ocurre por la forma de ser del millonario huérfano. Esto es, un demente psicópata.

La historia (que repito, es inverosímil y tiene demasiados hoyos) me parece que consigue rematar bien una triología que ha sido sin duda alguna magistralmente ejecutada. El elenco es espectacular; regresan todos los que habían salido (y que no hubieran muerto), incluidos fabulosos cameos de Liam Neeson y Cillian Murphy, y además se agregan de forma espléndida Tom Hardy, Joseph Gordon-Levitt, Marion Cotillard y Anne Hathaway.

El primero hace una interpretación muy original e interesante de Bane, si bien no tiene tanto que ver con el personaje de los cómics. De cualquier forma sí consigue mostrarse como un enemigo formidable para Batman, aunque es su presencia la que hace que en muchas escenas la película se tome demasiado en serio. Gordon-Levitt da un papel decente, si bien no espectacular, del sucesor de Bruce Wayne como Batman; y dado que nunca aparece con el traje (pero sí en la baticueva) no me extrañaría ver una película de Nightwing en el futuro. Marion Cotillard a mí me engañó por completo; cuando se acuesta con Bruce Wayne y después todo el mundo la trata como su novia, yo todo el tiempo me decía “¿quién es esta pinche vieja advenediza, y por qué todo mundo la trata como la novia, cuando obviamente la buena es la Gatúbela?”. No fue sino hasta el momento en que acuchilla a Batman que de inmediato me volteé y le dije a Isabel: Talia al Ghul. En retrospectiva era obvio, pero que lo hubieran guardado para el final de la película se me hizo maravilloso.

Anne Hathaway merece una mención especial: se roba todas las escenas donde aparece, y también todas donde no. No sólo es bellísima la cabrona; es la mejor adaptación que he visto de Gatúbela en toda mi vida. Michelle Pfeiffer y Julie Newmar no le llegan a los talones; la Hathaway muestra a la ladrona como siempre ha salido en los cómics: sexy, divertida, inteligente, y sin aguantarle nada a nadie. Que le den un final feliz a Bruce Wayne con Selina Kyle es de las razones por las que me gustó tanto la película.

Lo demás es lo que ya damos por hecho estos días: buenos efectos especiales, una espectacular música, y hartas explosiones.

Salí bastante contento del cine; sin embargo, lo triste es que esta película es sin duda alguna un final (me parece que sería un error garrafal el tratar de sacar una cuarta), y DC ha usado ya su mejor (y podríamos decir único) cartucho en el género de superhéroes. El año que viene saldrá la nueva película de Superman, y si la gente de DC fuera lista estarían pensando en adaptar a los otros miembros de la Liga de la Justicia (la Mujer Maravilla, Flash, tal vez reintentarlo con Linterna Verde y reiniciar Batman), para en cuatro o cinco años sacar una película que le pudiera hacer competencia a Avengers. Pero dada la poca capacidad que han mostrado para manejar sus franquicias, la verdad lo dudo.

Independientemente de todo eso, The Dark Knight Rises es un final propio para esta triología de Batman, y una película increíblemente entretenida, y en muchas partes muy divertida. Así que les diría que la fueran a ver, pero dado que ha ganado casi mil millones de dólares en taquilla, es muy probable que ya lo hayan hecho.

Imprimir entrada Imprimir entrada

Valiente

Por último, hace una semana, fuimos a ver Brave. Se aplican yada yada.

Brave

Brave

Tenía muchas ganas de ver esta película; porque se veía increíble, porque es de Pixar, y porque el elenco me parece maravilloso. Salí algo decepcionado del cine.

En primer lugar, no pudimos encontrar la película en inglés y en 2D; a mí no me gusta el 3D, pero Isabel senciallmente no puede ver las películas así, por lo que la vimos en español. Y luego sencillamente la película resultó ser demasiado para niños.

Sé que suena medio idiota quejarse de que una película para niños es demasiado para niños, pero una de las cosas en general maravillosas de las películas de Pixar, es el hecho de que generalmente son muy buenas para adultos también. Brave no es así, y sí es demasiado infantil en muchas partes.

Por último, y esto para mí sí es un deal breaker, la película no tiene absolutamente nada de romance. Es una historia de una princesa adolescente “rebelde”, y cómo llega a entenderse con su estricta e inflexible madre. Lo cual ha de ser fabuloso para adolescentes que se creen “princesas” y “rebeldes”, pero a mí me dio más bien hueva.

Estoy siendo algo duro con la película; la verdad es que sí está muy bien hecha (el pelo de Merida, y algunas escenas con partículas de agua en particular son impresionantes), sí es muy divertida la mayor parte del tiempo, y la historia está bonita. Sólo que yo creo que pude haberla visto en Blu-ray sin muchos problemas.

Si tienen niños chiquitos (o adolescentes que se creen “princesas” y “rebeldes”), no duden en verla. Si no, igual y vale la pena; sólo sí me parece que no está al nivel del estándar normal de Pixar.

Imprimir entrada Imprimir entrada

El Sorprendente Hombre Araña

Un par de semanas después de ver Dark Shadows, fuimos a ver The Amazing Spider-Man. Se aplican ya saben.

The Amazing Spider-Man

The Amazing Spider-Man

Yo he sido fan de Spidey desde que era niño, cuando pasaban sus caricaturas en la tele. Siendo adolescente hubo un momento en que sólo me faltaban seis o siete números para tener todo lo que se había publicado del superhéroe aquí en México, a partir de que Novaro tomara en sus manos la publicación del cómic a inicios de los ochentas, para que luego Editorial Vid se hiciera cargo a finales de los noventas. Cuando Marvel comenzó a publicar directamente sus revistas aquí en México dejé de seguirle el paso, y de hecho ya tiene años que no leo cómics regularmente; sencillamente no tengo tiempo.

De cualquier forma, Spider-Man siempre ha sido uno de mis superhéroes favoritos, y aunque disfruté mucho las tres películas de Raimi/Maguire, la verdad es que el último nunca me pareció la mejor elección para interpretar a Peter Parker. Andrew Garfield en cambio es perfecto para interpretar a Parker, además de que presenta una caracterización del personaje mucho más moderna; el original Parker adolescente era un adolescente de los sesentas; mucho ha cambiado desde entonces. Tengo entendido que esta modernización está relacionada con el universo Ultimate de Marvel, pero no me consta porque nunca lo he leído.

Como sea, la película es excelente en casi todos los sentidos; y en gran medida lo es no sólo por el fabuloso Garfield, sino por una espectacular Ema Stone convirtiéndose de forma absoluta en Gwen Stacy. Lo único malo de tener a Gwen en estas películas, es que ya sólo estoy esperando con tristeza a que la maten, como me pasé toda esta película esperando que mataran a su padre.

No voy a hablar mucho más de la película; el elenco es perfecto, la historia es entretenida, los efectos son fabolosos, y tienen que ir a verla, cosa que probablemente ya hicieron. Y si no, háganlo.

Imprimir entrada Imprimir entrada

Sombras Tenebrosas

Hace semanas fui al cine, pero no había podido publicar al respecto porque Xochitl (la venerable y anciana máquina que alberga mi blog) se cayó durante las vacaciones de verano. Fuimos a ver Dark Shadows, porque somos fans de Johnny Depp y de Tim Burton.

Se aplican las de siempre.

Dark Shadows

Dark Shadows

La película está basada en una telenovela gringa (soap opera, que así les dicen allá). Yo en mi vida la vi, y de hecho jamás había oído hablar de ella. Sin embargo, suelo confiar en Tim Burton y Johnny Depp, y en los avances se veía divertida, así que fuimos a verla.

La historia es muy idiota; en el siglo XVIII, el acaudalado Barnabas Collins se hace amante de una bruja (la estupidizantemente hermosa Eva Green), pero no corresponde su amor, así que la bruja mata a sus padres primero, después a su prometida, y por último convierte a Barnabas en güampiro. Para cerrar con broche de oro, lo encierra en un ataud, y lo entierra, donde el pobre güey permanece durante casi doscientos años.

Cuando por fin escapa, y después de escabecharse a los pobres trabajadores que lo desentierran, Barnabas regesa a su mansión para descubrir que su familia ha caído en la desgracia, en no menor medida porque la bruja (que sigue viva, haciéndose pasar por la tátara-tátara-tátara-tátara-tátara-tátara-nieta de ella misma) así se ha encargado de que ocurra. El caos se sigue.

La película es muy divertida en varias escenas que juntas duran como veinte minutos. Todo lo demás es medio incoherente, burdo, y en la mayoría de las veces muy, muy idiota.

Aunque no sufrí viéndola, ciertamente me pude haber esperado a verla en Blu-ray, si acaso. Tiene varias puntadas muy buenas, Depp es un pinche genio y lo rescatable de la película lo es en gran medida por él, y de verdad Eva es tan hermosa que hasta distrae por su belleza. Pero no es realmente recomendable para verla en el cine; no que importe demasiado, ya que probablemente no siga siendo proyectada en ningún lado.

Imprimir entrada Imprimir entrada

Voten

Salí a votar a las 7:40 AM, y llegué a la casilla al cinco para las ocho. Cuatro horas después, emití mi voto.

El dedo

El dedo

Ese es mi castigo por venir a Ixtapa-Zihuatanejo en día de elecciones. La casilla estaba hasta su madre; mucho tiene que ver que era casilla especial, en medio de un complejo turístico, pero al parecer sí está saliendo mucha gente a votar.

Así que hagan lo mismo.

Imprimir entrada Imprimir entrada

Blanca Nieves y el Cazador

El viernes pasado fuimos a ver Snow White and the Huntsman, a insistencia mía. No escribí al respecto porque no he tenido tiempo esta semana.

Se aplican ya saben.

Snow White and the Huntsman

Snow White and the Huntsman

Voy a suponer que nadie necesita un resumen en general de la historia. A mí me gustó muchísimo esta película por varias razones: es una modernización interesante (si bien no necesariamente inteligente) del cuento clásico de Blanca Nieves; Chris Hemsworth es endemoniadamente simpático; los siete enanos están muy cagados; Kristen Stewart agrega una expresión más a su anterior portafolio de dos expresiones faciales (la nueva es “te voy a matar, pinche vieja”); y muchas más razones en el aspecto técnico, como la buena utilización de efectos especiales, música, vestuario, etc., etc.

Sin embargo, la razón más importante por la cual me gustó esta película, es sin duda alguna Charlize Theron, que en mi opinión debió recibir primer crédito porque ella en gran medida sostiene la película, y podemos discutir que la historia relata más a bien a su personaje, aunque su nombre no aparezca en el título.

La Theron no sólo se ve guapísima la maldita, además interpreta su papel con tanto gusto que es casi indecente ver cómo se divierte haciéndolo. Además de que por supuesto su personaje es como catorce millones de veces más interesante que Blanca Nieves, el susodicho cazador, o los cagados enanos, con un odio y rencor hacia los hombres no completamente desubicado.

Por lo demás, es un cuento de hadas; hay princesas, caballeros, y no poco importante para el género, hadas de hecho. Sólo se hace un intento de “modernizarlo”, donde por “modernizar” se entiende hacerlo un poco más oscuro, si acaso se podría oscurecer más un cuento para niños donde una reina malvada le paga a un cazador para que le saque el corazón a Blanca Nieves y se lo lleve como prueba de que de hecho la mató. Así era la versión “original” del cuento, aunque claro es difícil definir “original” para estas leyendas europeas.

La película tiene sus problemas, pero a mí me gustó bastante y me estaba meando de la risa durante casi todo el tiempo que estuvo proyectándose. No me parece que los realizadores esperaran realmente que esa fuera la reacción de los espectadores, pero el resultado es entretenido al fin y al cabo. Sorprendentemente además hay promesas (o amenazas) de que harán la segunda parte, y me parece que yo podría ir a verla sin mucha resistencia: ciertamente será interesante ver qué tanto más pueden exprimirle a una historia tan idiota.

Imprimir entrada Imprimir entrada

Las elecciones presidenciales

Hace un rato que he estado ponderando escribir acerca de las elecciones; mi trabajo en mi tesis doctoral, así como otras circunstancias, lo habían impedido. Sin embargo, llevo con una tos espantosa más de una semana que me ha impedido trabajar como quisiera, y en este tiempo he estado pensando acerca de esta entrada, así que por fin me decidí a escribirla.

Hace poco más de seis años escribí una entrada, Porqué voy a votar por el PRD y el Peje, donde explicaba por qué votaría como lo hice en el 2006. Mi razonamiento para votar por Andrés Manuel López Obrador y (hasta cierto punto) el PRD siguen básicamente siendo los mismos; aunque las circunstancias se han vuelto más apremiantes, lo cierto es que el PRI y el PAN tienen para motivos prácticos el mismo proyecto de gobierno, y que el proyecto alternativo de nación que el Peje y su Movimiento de Regeneración Nacional (MORENA) es el único que ofrece una alternativa a la misma política social y económica que ha destrozado el país desde 1982, cuando Miguel de la Madrid tuvo a mal en convertirse en el primer presidente neoliberal de esta nación.

Cuando en el 2000 la bola de idiotas que promovió la estúpida idea del “voto útil”, un montón de gente lo dijimos: con Fox, al país le va a ir de la chingada. Tuvimos razón, por supuesto; el cambio de presidente de uno del PRI a uno del PAN no modificó en casi nada lo que hicieron los gobiernos priistas de de la Madrid, Salinas y Zedillo. Cambiaron las caras, y hubo algunos ajustes en los grupos de poder; pero para motivos prácticos todo siguió igual, y un montón de cosas empeoraron: en particular, al PAN (ni mucho menos a FOX) jamás le ha interesado realmente la cultura, el desarrollo científico, ni la educación pública, y esos tres rubros sufrieron acordemente.

Cuando en 2006 los mismos idiotas, junto con otros que lo único que temían era que sus privilegios fueran afectados, vociferaron que el Peje era un “peligro para México”, un montón de gente volvimos a decir: con otros seis años de PAN, al país le va a ir más de la chingada.

No sólo volvimos a tener razón; nuestros peores temores fueron altamente superados. El fraude electoral de 2006, donde Calderón “ganó” por 0.56 puntos porcentuales (dícese, ni uno completo), después de una asquerosa guerra sucia, de una intervención ilegal de Vicente Fox (que descaradamente después diría que él, personalmente, le había “ganado” al Peje), y de un IFE tan parcial que lo único que pudo hacer fue renunciar a su cúpula, llevó de manera viciada de origen a un “gobierno” de la República que ha resultado en el sexenio más catastrófico que hemos tenido en varias décadas.

Decenas de miles de muertos en una guerra inútil e idiota contra el narcotráfico; un gabinete formado por políticos de tercera y cuarta categoría incapaz de gobernar al país; una economía cada vez más débil y que genera cada vez más pobreza y desempleo (y por lo tanto cada vez más crimen y violencia); un abandono absoluto de la educación pública (cuando no la ataca de frente, como es el caso de la prueba ENLACE); y un mal manejo de los bienes de la nación, en particular, preocupantemente, los energéticos, con PEMEX en una condición desastrosa, y la CFE concesionando (de nuevo, ilegalmente) la producción de electricidad a empresas extranjeras… después de deshacerse (ilegalmente también) de Luz y Fuerza del Centro y uno de los pocos sindicatos que se oponían de manera inteligente a este régimen ilegítimo.

Todo lo anterior resulta en que el PAN va a perder en el 2012, por suerte; nada ni nadie puede cambiar ese desenlace para la pobre y patética Josefina Vázquez Mota. No sólo porque es pésima candidata, ni porque recibe madrazos no sólo de sus adversarios (que en las últimas semanas ya mejor la ignoran, porque sus posibilidades de ganar se han reducido de forma irremediable); sino de su propio partido, de su propio equipo de campaña, y (por supuesto) del propio Calderón. El voto de castigo que ese partido se ganó solito durante los últimos 12 años será implacable, y espero que mis compatriotas hayan aprendido la triste verdad de la patética derecha de este país: sencillamente no sabe gobernar.

Desde hace unos años yo he estado convencido: el PAN resultó peor que el PRI, y si esas fueran las únicas opciones, yo votaría por el PRI, que incluso en la terrible mediocridad de de la Madrid, la incapacidad política de Zedillo, o la venenosa inteligencia de Salinas, fueron mejores gobernantes de lo que el PAN jamás (con su actual dirigencia y militancia) será capaz de ser.

Por suerte, PAN y PRI no son las únicas opciones.

Desde hace al menos tres años (aunque realmente lleva más tiempo), cuando Televisa y otros grupos de poder en México se dieron cuenta de que las posibilidades de reelección del PAN se disminuían cada vez más (era y es fácil verlo, dada su inusitada incompetencia), en bloque decidieron que el próximo presidente de México debía de ser alguien que en primer lugar les garantizara que sus privilegios (varios de ellos ilegales) no serían tocados, y en segundo lugar que lo pudieran controlar, a cambio de (en gran medida) el control de los medios electrónicos que tienen.

Desde su punto de vista tiene sentido: los niveles de aprobación del PAN se estaban (y lo siguen haciendo) despeñando ante la opinión pública, y entonces un regreso del PRI no sólo era posible, sino altamente probable. Entonces durante estos años manejaron la imagen de un Enrique Peña Nieto ganador de las elecciones del 2012, aunque faltaran decenas de meses para que esto ocurriera. Es también importante entender que esta estrategia no sólo se centra en Peña Nieto: hay ya varios diputados y senadores del PRI y del PAN que están básicamente al servicio de Televisa, para que cosas como la Ley Televisa no les vuelva a ocurrir. Están protegiendo sus intereses, en detrimento de la democracia y libre expresión en México (nada más recuerden el caso de Carmen Aristegui).

Durante todo este tiempo Peña Nieto fue presentado como algo inevitable; no había ya nada que hacer, “todas” las encuestas mostraban que el candidato priista (meses antes de que de hecho fuera candidato del PRI) sería el presidente y no había nada que discutir.

A este grupo de poder, que le encantaría que la realidad fuera como ellos la presentan, se le olvidaron tres cosas:

  1. Enrique Peña Nieto es un mal candidato: inculto, torpe, autoritario y no particularmente inteligente.
  2. López Obrador lleva preparándose para el primero de julio casi seis años.
  3. Los estudiantes de este país, sorprendentemente comenzando con los de las escuelas privadas, no están dispuestos a que una televisora les imponga su próximo presidente.

Voy a hacer un paréntesis: aunque en principio y sin duda alguna apoyo a los chavos y chavas de #YoSoy132, lo cierto es que (en mi opinión) son muy inocentes (o muy pendejos) si siguen pronunciándose como “apartidistas”. En sus asambleas y movilizaciones la enorme mayoría de estos chavos expresa su rechazo tajante a Peña Nieto, y su completa descalificación del “gobierno” de Felipe Calderón. Bueno pues, dejen de hacerse güeyes y apoyen abiertamente a Andrés Manuel López Obrador. De otra forma, es básicamente llamar al voto nulo, que como toda persona con dos dedos de frente sabe, es igual de inútil que abstenerse.

Otro paréntesis: si las elecciones en México fueran por mayoría calificada (50% + 1), el voto nulo no sólo no sería inútil; sería un arma bastante filosa. Pero como en México gana el que tenga mayoría simple (así sea una “mayoría” de 10%), el voto nulo es completamente inservible. Uno de los candidatos presidenciales en la boleta ganará la presidencia, y anular el voto no evita en nada eso: no va a cambiar absolutamente nada. El que sea que gane el primero de julio (y de verdad quiero decir el que sea) le va a valer absoluta y completamente madres si el 75% de los votos que lo lleven a la presidencia son nulos.

Las últimas encuestas muestran una tendencia que debe aterrar al grupo de poder que quiere a Peña Nieto en la Silla del Águila; el Peje sube y sube y sube, y EPN y JVM bajan y bajan y bajan. Quadri no importa; nunca ha importado, y ha quedado tan profundamente descalificado por su relación con Elba Esther Gordillo que realmente ya nunca importará. Por dichas tendencias este grupo de poder (comenzando por Televisa) ha comenzado un refrito de la guerra sucia que vimos hace seis años: espots televisivos mostrando a AMLO como un “peligro para México”. Después de los últimos 12 años de panismo, y de los últimos 30 de neoliberalismo, no sé cómo no se les cae la lengua para decirle a nada más un “peligro para México”.

Las tendencias además les preocupan por otras circunstancias: en el 2006, tres meses antes de las elecciones AMLO sólo bajó en las encuestas, no subió. Además, hace seis años la guerra sucia tardó más de un mes en comenzar a reflejarse en las encuestas. Ahora sólo faltan poco más de tres semanas para las elecciones, y es entonces muy posible que la guerra sucia no funcione; de cualquier forma esperen ver al Peje siendo atacado por absolutamente todo lo que haya hecho o dejado de hacer, no importa si fue antier o hace veinte años. Incluso ya lo están acusando de la devaluación del peso frente al dólar.

Si su guerra sucia no funciona, entonces el fraude es otra opción. La usaron en 2006; ¿por qué no de nuevo? Se ha reportado que las listas nominales muestran un aumento en la población rural (no la urbana), mientras que los datos del INEGI dicen exactamente lo contrario. Recuerden que el Peje tiene una ventaja absoluta (e incluso abrumadora) en los sectores educados de la población, y éstos se concentran en las ciudades; además de que el control de la maquinaria del PRI es mayor en las zonas rurales que en las urbanas.

Y si la ventaja del Peje para el primero de julio es tal que incluso un fraude no garantizaría el triunfo de EPN, no duden incluso escenarios que hace unos meses hubieran parecido impensables. No es completamente descabellado pensar que unos días antes de las elecciones Calderón (o el IFE, o quien sea) diga que no hay condiciones de seguridad para llevar a cabo las elecciones, y que éstas se posponen “hasta próximo aviso”. Es un escenario catastrófico; pero ciertamente no podemos descartarlo.

Mucha de la gente que ha expresado su intención de votar por Andrés Manuel López Obrador lo hace bajo el argumento de que es “lo menos peor”. Yo no caigo en ese grupo; yo sinceramente creo que es la mejor opción que tiene el país. No por el Peje; como escribí hace seis años, el tipo nunca me ha caído bien, y de hecho sigue cayéndome mal. En particular cuando empezó con sus mamadas de la “República amorosa” no tienen idea de lo mal que me cayó; por suerte al parecer ya superó esa idea idiota.

No; lo importante es el proyecto de nación, que no es una idea fabulosa que él haya tenido, inspirada por ángeles o el espíritu santo. Ese proyecto de nación es el resultado de décadas de discusión de la izquierda mexicana, comenzando realmente con el movimiento estudiantil de 1968. Mucho más que el Peje, el proyecto de nación es lo que a mí me atrae, particularmente por el gabinete que ha anunciado que formará su gobierno. La mayoría de los miembros de ese gabinete son expertos en sus temas, y gente que sin duda está dispuesta y es capaz de implementar dicho proyecto.

Yo no voy a votar por el Peje por razón de él; voy a votar por el Peje por razón del proyecto que encabeza.

De la misma manera, no voy a votar ni por el PRI ni por el PAN no porque me caigan mal sus candidatos, o porque difiramos en ciertos principios. No voy a votar por ellos sencillamente porque gobiernan mal. Vean a la Ciudad de México en los últimos 15 años, y vean (literalmente) al resto del país. Vean lo que pasó en Atenco durante el sexenio de Peña Nieto en el Estado de México. Vean la violencia en lugares como Monterrey, tan exacerbada que hubo quienes se mudaron a la Ciudad de México por la violencia.

La Ciudad es de los pocos oasis de las desgracias que está viviendo el país, y en gran medida es por el gobierno que hemos tenidos en los últimos tres quinquenios, aunque gran parte también es por la fabulosa ciudadanía que aquí vive. Hago notar que estoy hablando en particular de los gobiernos de la Ciudad, no del PRD. En Chiapas, Guerrero y Michoacán las cosas están igual o más de la chingada que en el resto del país, y son estados gobernados por el PRD.

Pero los equipos que han gobernado la Ciudad (incluyendo el del Peje, por supuesto), han hecho las cosas más bien que mal; han cometido su bola de imbecilidades, claro, pero en general han gobernado bien. Y es sin duda de los gobiernos más progresistas de este país, donde las mujeres pueden decidir el futuro de su propio cuerpo, y donde dos personas que se aman se pueden casar, no importando de qué género sean. Uno de esos equipos es el que encabeza el Peje (aumentado y fortalecido por gente increíblemente capaz como Juan Ramón de la Fuente), y quiero que hagan por el país lo que hicieron por la Ciudad.

Los documentos que acaba de publicar The Guardian acerca de la participación de Televisa en la campaña de desprestigio contra el Peje, me parece serán la pistola humeante que muchos de los indecisos necesitaban para decidirse a votar por él. No es seguro, y no será fácil; pero sí es posible que el Peje gane el primero de julio, y hay múltiples señales que apuntan a ello, como Peña Nieto comenzando a decir que la única encuesta importante es la del día de las elecciones, o un aterrado Fox llamando a votar en contra de su partido.

Va a venir el lodazal, y tal vez incluso peores escenarios como el uso del fraude, o incluso el tratar de posponer o cancelar las elecciones. Pero conforme más gente se informe y decida salir a votar ese día, más difícil será que eso ocurra; no hay forma de garantizar que no ocurra, pero sí se le pueden poner piedras al camino de esos escenarios.

De forma muy paradójica, de alguna manera es más probable que gane el Peje ahora que en 2006. Muchísimos empresarios y gente de clase alta lo están apoyando; los primeros porque en este país no hay realmente libre mercado, uno tiene que ser amigo de alguien dentro de los grupos de poder para que realmente el mercado le sea “libre”. Los segundos porque la gente con recursos está despertando a la espantosa realidad de que sus hijos no tienen futuro con estos regímenes. Por eso fue la reacción tan inusitada de los estudiantes de la Ibero, y por eso fue que en el Tecnológico de Monterrey en Monterrey recibieron al Peje bajo gritos de “¡Presidente, presidente!”. Sus padres se gastan miles de pesos en universidades privadas, y al salir tienen las mismas dificultades que todos el resto de los mexicanos para encontrar trabajo.

Sólo un puñado (muy poderoso) con los conectes necesarios está beneficiándose de este “gobierno”; y eso no va a cambiar con Enrique Peña Nieto; mucho menos con Josefina Vázquez Mota (que de cualquier forma va a perder, entonces no importa). Si el resto de nosotros queremos una oportunidad, las cosas deben de cambiar.

Y el único que ofrece una posibilidad real de cambio, es Andrés Manuel López Obrador.

Como lo he dicho muchas veces en este blog: no me crean nada a mí. Infórmense, vean la historia, logros y errores de cada uno de los candidatos y de sus partidos, y salgan a votar el primero de julio. No votar o anular el voto es una irresponsabilidad y (desde mi punto de vista) una cobardía: es como el niño que agarra sus canicas y se va a su casa porque el juego no les gusta. La diferencia primordial es que en ese “juego” se va el futuro de la nación y de millones de mexicanos, porque agarren o no sus canicas, uno de los candidatos disponibles va a sentarse en la silla del águila. Les guste o no les guste.

Y a los que no les gusta ninguno de los cuatro candidatos; no pueden culpar a nadie excepto a ustedes mismos. La clase política mexicana no va a generar candidatos decentes mágicamente: la única forma de que comience a hacerlo es que todos, como ciudadanos, participemos activamente en la política.

Salir a votar el día de las elecciones no es suficiente; pero es el mínimo indispensable. Así que háganlo, después de informarse.

Y vamos a ver qué resulta en tres semanas.

Imprimir entrada Imprimir entrada

Need for Speed: SHIFT

Despues de Grand Theft Auto IV, mi siguiente platino fue Need for Speed: SHIFT, en marzo.

Need for Speed: SHIFT

Need for Speed: SHIFT

Me gustan los juegos de carreras, y contrario a Burnout Paradise, NFS:S es un juego casi clásico de carreras. Con ello quiero decir que hay pistas (autódromos y partes de ciudades o campo), y el objetivo del juego en general no es estar chocando con los otros carros. El casi proviene de que no tiene opción de concursar por la pole position, que no hay pausas en pits, y que no tiene temporadas donde los mismos pilotos compiten en varias pistas por puntos, y al final gana el que más puntos tiene.

Es una lástima; si hubiera tenido al menos la oportunidad de concursar por el pole position y pausas en pits, yo creo que este juego me hubiera gustado más que el clásico Indianapolis 500: The Simulation, el cual jugué hasta la ignominia en una de las compus que tuve cuando era adolescente.

NFS:S lo compré de la manera más fortuita; fui al Best Buy de Acoxpa hace poco más de un año a comprar el Blu-ray de Minority Report, y lo vi baratísimo, como en 250 pesos si no mal recuerdo. Lo compré, lo puse exactamente una vez en mi PS3 antes de mi viaje de seis meses por Europa, Canadá y EU, y hasta enero de este año comencé a jugarlo regularmente.

Aunque NFS:S no es tan insoportablemente detallado como Gran Turismo 5, está bastante bien hecho. Por ejemplo, si uno se detiene puede ver el asfalto y las hebras de pasto, y lo carros todos se ven preciosos bajo los distintos climas que el juego presenta. El sonido es todavía mejor, y la sensación de velocidad con los carros más rápidos es bastante creíble. La inteligencia artificial de los demás pilotos es decente, si bien después de no mucho uno aprende a ganarles con un carro mediano; con un súper carro es trivial.

Sacar el platino de NFS:S fue relativamente fácil, excepto por un trofeo. El juego tiene un sistema de “medallas” internas, y son 26 en total; uno de los trofeos consiste en obtener 20 medallas. Una de las medallas es dominar todas las esquinas de todas las pistas; casi todo mundo recomienda mejor sacar una de las 6 medallas en línea, pero yo me puse de necio (además de que no quería repetir la experiencia de GTA IV) y terminé dominando todas las esquinas del juego. Lo cual tal vez no sería difícil, si tuviera un volante; con el estúpido control Dual SHOCK del PS3 es bastante desesperante.

Como sea; NFS:S es bastante divertido, y yo creo que volveré a él para sacar todas las estrellas del juego (uno gana estrellas por el lugar en que queda, y por acciones como terminar una vuelta en algún cierto tiempo, o por sacar pilotos de la pista), y no me extrañaría en algún momento comprar la secuela, SHIFT2. Por el precio en que lo encontré, ciertamente vale mucho la pena.

Imprimir entrada Imprimir entrada

Nada más que no tarden igual en responder

En diciembre de 2006 fui a un taller organizado por mi director de tesis de la maestría (y director actual en el doctorado), en Guanajuato. Escribí al respecto en su momento.

En dicho taller presentaron un problema. La historia de ese problema y cómo lo resolvimos es larga, embrollada, e involucra a cuatro países. El punto es que hoy, cinco años y cinco meses después, por fin envié el artículo correspondiente a una revista.

Ahora sólo falta esperar a ver qué nos dicen.

Imprimir entrada Imprimir entrada

Pina

El viernes de la semana pasada fuimos a ver Pina. No había escrito al respecto por andar ocupado, y porque además no fue mi idea ir a verla.

Diría que se aplican mis advertencias de spoilers normales, pero en esta película es absolutamente irrelevante.

Pina

Pina

La danza moderna/contemporánea siempre me ha dado una hueva infinita. Me queda clarísimo que estoy siendo terriblemente injusto, pero en mi opinión la enorme mayoría de la gente que hace danza moderna/contemporánea, es porque no puede hacer ballet, que ese sí siempre me ha gustado muchísimo.

Ese es mi llano gusto; de todas formas creo que un documental de danza moderna/contemporánea podría gustarme mucho, porque un documental para ser bueno no tiene necesariamente que ser acerca de un tema que me agrade.

Este documental de Wim Wenders a mí me dio tanta o más hueva que el tema que trata, entre otras cosas porque no es un documental de danza moderna/contemporánea, ni tampoco es un documental de Pina Bausch. Es una serie de entrevistas sin ton ni son, intercaladas con partes de coreografías de Pina interpretadas por su compañía de toda la vida. En 3D, porque la película no se presenta en ningún otro formato.

El documental no es de danza moderna/contemporánea porque en ningún momento explican absolutamente nada acerca de la danza moderna/contemporánea, así que o el espectador ya sabe de qué va la cosa, o se jode y se queda con su impresión original de la misma. Lo que en mi caso resultó en pasar la mitad de la película muriéndome de hueva, e incrédulo acerca de lo pretencioso del asunto.

El documental tampoco es de Pina Bausch, porque en ningún momento relatan absolutamente nada acerca de ella; no se sabe dónde nació, donde creció, qué estudio, qué pensaba, ni nada así. Todo lo que la película transmite acerca de ella son unos comentarios vagos que dan los miembros de su compañía, y las coreografías, que en mi caso (repito) sólo me transmiten el arte de una persona que me da más bien hueva, y que me resulta altamente pretencioso.

Para acabarla de joder, la película está en 3D, para que nos “sintamos” como si estuviéramos frente a una compañía de danza en cuerpo y alma. Siendo justo, el 3D de Wim Wenders hace un par de cosas más interesantes que lo que hacen la mayor parte de las otras películas; pero no compensan en lo más mínimo todo el resto de la película que me dio hueva.

Cada vez que hacían una “entrevista” (si se le puede decir entrevista el filmar a alguien en tres cuartos mientras rememora cualquier pendejada intrascendente), de repente ponían al entrevistado a bailar solo, no con el resto de la compañía. Estas pequeñas coreografías individuales sí hubo dos o tres que me gustaron; son las coreografías que involucraban a más miembros de la compañía las que me dieron una hueva infinita. Aunque debo reconocer que hubo un par de ocasiones donde los bailarines hicieron cosas que físicamente sí se ven muy difíciles; siguen sin gustarme, pero sí debe ser difícil el poder hacerlo.

También es indudable que hacer danza moderna/contemporánea es muy buen ejercicio; los hombres y mujeres de la compañía de Pina en general ya no son jóvenes, y tienen unos cuerpos admirables.

Si les gusta la danza, esta cosa de Wim Wenders probablemente les guste. A mí me estaban dando ganas de pegarle a alguien cuando la vi.

Imprimir entrada Imprimir entrada

Extensiones

Isabel y yo tenemos cinco computadoras; dos laptops, mi computadora de escritorio, el servidorcito con procesador atom donde bajamos cosas, y mi media center. Si incluimos al PS3, son seis computadoras. Si incluimos el iPad de Isabel, son siete. Si incluimos nuestros teléfonos (que se puede argumentar que cuentan como computadoras), entonces son nueve.

Dado que seis de esos aparatos vinieron conmigo cuando me mudé con Isabel, no es de extrañar que el costo de la luz se haya incrementado por mucho (el horno de microondas, y mi tele de 46 pulgadas también deben influir). Eso implicó que empezáramos a hacer ciertos ajustes para disminuir nuestro consumo eléctrico.

El más obvio y sencillo fue el apagar algo cuando no se esté usando; lamentablemente es también el más incómodo en mi máquina de escritorio. Durante mi viaje de seis meses el año pasado, me acostumbré a trabajar en mi laptop, la cual nunca apago, a menos que le actualice el kernel o algo similar; en general sólo la suspendo, y entonces es básicamente instantáneo el regresar a trabajar: todas mis aplicaciones están abiertas tal cual antes de que la suspendiera.

Mi máquina de escritorio no tenía esto, y entonces sí es medio desesperante el prenderla y apagarla; no tanto por el tiempo que toma (es rápida al fin y al cabo), sino por el necesario esfuerzo de reconstruir mi estado de trabajo, dícese empezar mis aplicaciones y abrir mis documentos. Hoy por fin me puse a hacerle trutú a mi PC, y conseguí que suspendiera básicamente igual que mi laptop. La verdad me impresioné; nada más encontré la opción en el BIOS que lo permite, jaló de inmediato con Linux.

El problema es que suspender mi escritorio implica que tengo que dejarlo “prendido”. El CPU y discos duros están apagados, pero la máquina sigue consumiendo energía para mantener la memoria RAM activa, que es como funciona cuando uno la suspende. En la laptop no es tanto problema porque consume mucho menos electricidad que mi máquina de escritorio. Además, está el problema de que si se va la luz, pierdo todo (por lo anterior); en la laptop esto no pasa porque tiene batería.

Así que, después de años de no usarlo, investigué cómo hacer que mi máquina de escritorio hibernara. Hibernar es básicamente igual a suspender, sólo que los contenidos de la memoria van al disco duro en la partición del swap, y entonces la máquina se puede desconectar completamente. Al prenderse de nuevo, lo primero que hace Linux es restaurar los contenidos del swap a la memoria, y entonces todo regresa a como estaba. El proceso tarda un poco menos que prender la máquina de cero, y tiene la infinita ventaja de que el estado de la sesión de trabajo se preserva de modo perfecto; o en otras palabras, ya no tengo que iniciar mis aplicaciones ni reabrir mis documentos.

De todo ese choro no es esta entrada; la entrada es acerca de que GNOME no tiene una opción en su menú de estado para hibernar la máquina. Joder, con esfuerzos tiene una opción para apagarla; los genios de GNOME decidieron que todo mundo debería siempre suspender su computadora, y para poder apagarla uno tiene que presionar la tecla Alt para que la opción aparezca en el menú de estado.

Así que me fui al sitio de extensiones para el GNOME Shell, y busqué “hibernate”, y luego luego me salió la extensión Alternative Status Menu. Eso no tiene nada de sorprendente; lo ingenioso es que si visitan esa página con GNOME 3, aparece un botón para habilitar o deshabilitar la extensión. Así es, la pueden habilitar o deshabilitar desde el navegador (yo uso Chromium, pero al parecer funciona con Firefox y obviamente con Epiphany, el navegador de GNOME). Así que le hice click al botón, y de inmediato mi menú ganó la habilidad de apagar o hibernar sin tener que presionar teclas mágicas.

Menú de estado

Menú de estado

Por supuesto ya había leído al respecto, pero verlo funcionar sin que yo jamás hiciera nada sí me pareció sorprendente. No he jugado mucho con las extensiones del GNOME Shell (tengo sólo dos o tres), pero ésta es la primera que activo desde el sitio de extensiones, y la verdad estoy encantado con los resultados. De hecho, hasta me dan ganas de programar unas cuantas yo mismo.

Como sea, ya no tengo que preocuparme de restaurar el estado de mi escritorio cada vez que apago mi máquina; y si sólo dejo de trabajar un rato (porque voy a comer o algo así), puedo sólo suspenderla.

Y se quejaban de que GNOME 3 no ofrece suficientes opciones.

Imprimir entrada Imprimir entrada