A blog about data, information and Tech by Mario Alberich

        

ene. 5
2014

Enlaces de interés 2014-1

 

Y para acabar un vídeo totalmente contrapuesto al del último del 2013: Martin Kleppe y sus 1024 segundos de magia (con Javascript).

Si lo vas a ver, prepárate para pausar y rebobinar unas cuantas veces. Y buena suerte con el jsfuck :-D.

Read more »

ene. 2
2014

#hhvm en #magento y #symfony

A partir de lo comentado en el anterior artículo sobre HHVM, me quedaba por aclarar su funcionamiento con la herramienta PHP más popular para crear sitios e-commerce: Magento.

Magento es uno de los casos más evidentes de la lentitud de PHP para aplicaciones medianamente grandes. El caso de Magento es el de una aplicación que utiliza varios miles de clases, con una estructura de directorios en los que se buscan estas clases, y en un proceso de interpretación del código que provoca una ejecución lenta. A pesar de usar PHP de forma intensiva (si no lo haces, puedes morir en el intento), Magento es lento. Y parte de la responsabilidad de ese hecho es de PHP.

Así que una vez aceptado el problema, HHVM puede ser la solución. ¿Cómo funciona HHVM con Magento? Pues la respuesta: no funcionaba. HHVM no incluye de serie algunas funcionalidades necesarias para Magento.

Adaptar HHVM, adaptar Magento


Mejorar el rendimiento de Magento es un objetivo común en todo el ecosistema de Magento, por eso no se hizo de esperar un análisis sobre el proceso de adaptación de HHVM a Magento, y un poco más tarde una solución publicada en Github por Matheus Zeiss para poder ejecutar un Magento básico sobre HHVM.  Con esta implementación, podemos ver una muestra de importación de productos en Magento usando HHVM, que tiene una pinta impresionante:

magento-import-test-hhvm from derp on Vimeo.

También podemos ver unas instrucciones de Cyrill Schumacher en Github para ejecutar Magento Enterprise Edition con HHVM, o el proceso de reindexación ejecutado por Daniël Sloof y mostrado en una captura de pantalla en su cuenta de Twitter.

¿Y ya está? ¿Magento funciona sobre HHVM? Para nada. Cada nuevo módulo que se instale en Magento deberá ser probado para que funcione sobre HHVM, y en caso contrario modificar su código. O eso, o bien esperar a que HHVM vaya incorporando esas funcionalidades.

Symfony


Symfony, el Framework PHP que tiene más estrellas en GitHub, es otro de los agraciados con la mejora de rendimiento. Además de las mejoras publicadas en los tests del blog de HHVM, hay otras pruebas más básicas realizadas con ApacheBench. Digna de mención es esta presentación en Slideshare sobre HHVM y Symfony:

Read more »

dic. 30
2014

Si desarrollas en #PHP y tienes un rato, prueba #HHVM

Después de estos años trabajando con PHP, una cosa queda clara: a partir de un cierto punto, el uso de memoria y de CPU son elementos limitadores en el rendimiento de nuestras aplicaciones. Con el tiempo y la introducción de frameworks de desarrollo, el consumo de recursos se incrementa notablemente, y aunque el coste de la RAM se ha reducido, esto no es un argumento aceptable: si hay lenguajes más eficientes acabarán siendo los preferidos, especialmente en un momento en el que los buscadores exigen el mínimo tiempo de respuesta.

HipHop para agilizar PHP


Hace algo menos de 3 años Haiping Zhao anunció en el blog de desarrolladores de Facebook la disponibilidad de HipHop para PHP, una herramienta para generar código C++ optimizado a partir de PHP. Esta primera aproximación (que empezaba en el 2008) dejaba fuera del proceso de traducción funcionalidades tales como eval().

Aunque el objetivo no es nuevo (APC, eAccelerator y el Zend Engine van en una dirección similar), la aproximación en aquel momento fue diferente: HipHop convertía el código en C++ (para luego compilarlo), no en opcode (para luego ejecutarlo sobre el propio motor de PHP).

Esta mejora en la ejecución tampoco redundaba en mejoras de velocidad para otras operaciones, como por ejemplo consultas de la base de datos: si el cuello de botella de una aplicación estaba en ese punto, el resultado final no mejoraría significativamente. Aún así, la promesa de un PHP más eficiente en el uso de la CPU y de la memoria era generar unas altas expectativas. Desde entonces el proyecto ha ido evolucionando sin mucho ruido, y quizá debido a sus limitaciones, la implantación no fue extensiva.

De HipHop a HHVM


Casi dos años después, apareció el blog de HHVM, mostrando que Wordpress 3.4.2 podía correr sobre HHVM.

Sin embargo el proceso de HHVM es diferente al de HipHop.  En el caso de HHVM, se convierte PHP a un bytecode que luego es convertido a lenguaje máquina con un compilador JIT. Este procedimiento es similar al utilizado por la Máquina Virtual de Java, por ejemplo. Este cambio evita el proceso de compilación que sí requería HipHop, por lo que el proceso de actualización de código resulta más ágil con HHVM. Algunas de las ideas son similares a APC, pero desde luego el proceso no es el mismo. APC es un componente que se puede instalar aparte, y HHVM es la base sobre la que corre PHP.

Con el tiempo, la carrera se ha encaminado a tener una herramienta de aplicación en un espectro lo suficientemente amplio de frameworks y aplicaciones populares que asegure su difusión. Sin ir más lejos, actualmente no parece posible configurar HHVM para que utilice Apache, aunque está en su Roadmap.

En esa dirección, el pasado 19 de Diciembre se publicaba en el blog de HHVM un artículo sobre la ejecución de pruebas unitarias de diversos frameworks en HHVM. Desde el inicio de esas pruebas hasta el resultado final, la mejora ha sido notable en algunos casos (Symfony o Yii por poner dos casos populares), con una media de un 9.62% de la superación de pruebas unitarias, y una mejora del 16% del rendimiento (ojo, sobre la ejecución de la base de código de facebook.com).

En resumen, HHVM es a mi modo de ver un proyecto que hay que seguir de cerca. En un momento en el que PHP-FIG trabaja a fondo en las PSR y que el uso de frameworks es indiscutible para el desarrollo de aplicaciones web medianamente escalables, HHVM puede ayudar a dar el paso para superar los problemas de rendimiento de un lenguaje que no fue originalmente concebido para este enfoque.

He encontrado este artículo sobre las implicaciones del uso de HHVM, interesante lectura.

Read more »

dic. 29
2013

Enlaces de interés 2013-52

Hoy poca cosa por comentar, algunos enlaces dispersos para amenizar el domingo post-manjares.


Y para acabar, un video bastante alejado de lo que muestro habitualmente: Teaching to See. Introspectivo, relajante, sugestivo, sobre la experiencia de enseñar las bases del diseño y su aspiración por la simplicidad. Si tienes un rato, déjate llevar.

Inge Druckrey: Teaching to See from Edward Tufte on Vimeo.

En el fondo es mi deseo para vosotros durante el 2014: Aprender un poco más a ver lo que nos llegue por delante.

Read more »

dic. 23
2013

#github ya es más que un servicio para programadores

En una lectura veraniega el New Yorker repasaba la pequeña historia de Github, que a su vez es la pequeña historia de la colaboración en el desarrollo de aplicaciones, ya que Git surge de la necesidad de los desarrolladores de Linux por tener una herramienta que se adaptara mejor a su forma de trabajar, y en especial al número y organización de los programadores.

Del servicio al entorno social


Y lo cierto es que Github ha evolucionado. Aunque ya existen servicios para gestionar el código como Sourceforge o Google Code, Github ha conseguido capitalizar a la comunidad de desarrolladores. La facilidad para clonar, forkear y documentar las aplicaciones, generar documentación de la aplicación, entre otros; todas estas utilidades han facilitado el ascenso de github.

También es posible seguir (watch) un proyecto, marcar un repositorio como favorito, identificar el origen de los forks, comentar los cambios y proporcionar ejemplos (Gists), por lo que Github aglutina lo que es importante en un proyecto (comunicar, compartir y colaborar) con lo que lo hace social (la visibilidad para otros, su feedback y su ayuda).

Pero no hay que descartar otra vertiente: Github se puede llegar a convertir en una especie de LinkedIn o el CV del desarrollo. Este último paso, el profesional, es también digno de seguir. A su vez existen voces críticas con la visión de que Github no es tu CV, derivadas del hecho que el Open Source es mano de obra gratuita y las réplicas matizando la inutilidad de GitHub. Es un debate abierto que no tiene pinta de cerrarse en breve.

Del servicio a la metodología


El siguiente paso es el que merece más atención, porque sale del contexto del desarrollo. Se trata de utilizar Github com una herramienta de propósito general, algo que puedes conectar a tu procesador de textos y usarlo para redactar un manual, o simplemente un documento.  Github ya permite soportar la generación de páginas para el repositorio sitio, y en realidad existe una cantidad importante de repositorios que son también manuales, tutoriales o recopilaciones de buenas prácticas, consejos, etc.

Es decir, ¿Github a medio camino entre un interfaz para Git, y un google drive básico? Pues no tan básico: Github ya permite editar datos CSV directamente desde su entorno. Y probablemente se vayan sumando más utilidades del mismo estilo, para así facilitar la entrada a usuarios no-programadores.

Pero el paso más llamativo es el de Github and Government, un proyecto que aspira a facilitar y catalizar las iniciativas de Open Government proporcionando un entorno de colaboración con las herramientas del propio Github. ¿Y cómo va a funcionar esto? Pues quizá Clay Shirky tenga algo que explicarnos en este video, sobre cómo se podría redactar leyes utilizando herramientas de desarrollo de aplicaciones de software (y en concreto, Git):

[ted id=1546]

Me encanta cómo expone este hombre, para qué negarlo. Espero que os guste y os inspire igualmente.

¡Felices fiestas!

Read more »

dic. 22
2013

Enlaces 2013-51

dic. 19
2013

Aprender y enseñar visualización de la información

A pesar de ser una especie cuyo valor diferencial está en su capacidad para transmitir información verbalmente, a menudo da la sensación que las metodologías de aprendizaje aún distan de ser eficientes.  Sin bajar a la realidad de las políticas educativas, las técnicas pedagógicas se enfrentan a un reto importante: cómo transmitir los conceptos, procesos y criterios a un público heterogéneo.

Este punto es especialmente importante cuando tratamos áreas de conocimiento relativamente nuevas, como es el caso de la visualización de la información. Claro que sus ingredientes principales no son nuevos, pero la forma como se combinan sí lo son, y aún es pronto para saber las recetas que facilitan una visualización adecuada.

Y entonces, ¿Cómo podemos aprender y/o enseñar a visualizar datos? Hay varios recursos al respecto:


Hago un resumen de los puntos que me han parecido más interesantes.

Aprender visualización después de haber aprendido visualización


Resumiendo lo comentado

  • Trabajar con los datos: Como en cualquier actividad fuertemente basada en la técnica (que no tecnología), la experiencia con los datos se basa en trabajar con ellos. Puedes buscar repositorios sobre datos que te interesen, para añadir aliciente a tus análisis. Parte de ese proceso implica aprender y reforzar las técnicas, y a la vez las tecnologías asociadas. La otra opción
  • Buscar opiniones de terceros: Como contrapunto, después del esfuerzo por mejorar personalmente, es importante mostrar nuestros resultados a otros ojos. Las opiniones de los demás, salvo excepciones, aportan información sobre la dirección en la que mejorar.
  • Leer más: Después del proceso anterior, vale la pena (re)leer y buscar respuestas que otros han dado a las preguntas que te planteas.

Después de aprender, ¿Cómo enseñar?


Aunque en este punto se está enfocando a enseñar a profesionales, algunos de los aspectos son válidos para fines didácticos hacia el público en general.

  • Iteraciones en el desarrollo de materiales: Como en cualquier disciplina inmadura, enseñar visualización de la información tiene menos paradigmas, y por ello requiere más adaptación al público, tema y objetivos. Es por ello que los materiales didácticos variarán en más grado.
  • Linearidad en la exposición: Como oposición a lo anterior, la exposición debe ser linear para evitar las máximas dudas, ineficiencias. A pesar de ello debe acomodar la incertidumbre, creatividad y experimentación.
  • Craft vs. instructional: Buscar el balance entre los principios y reglas, y lo hecho a medida.
  • Convicciones: De lo anterior se deduce algo importante: para afrontar las novedades, los alumnos deben desarrollar sus propias convicciones, más allá de lo que gusta o no. Se trata de que identifiquen los atributos que les conducen a esa opinión.
  • Elecciones: Provocar que los alumnos tomen decisiones como actitud natural, y con sentido.
  • Variedad: El público objetivo al que se dirige esa formación contará con una gran variedad de perfiles, desde tecnológicos hasta artísticos. Ningún estándar encaja en esta variedad, hay que ajustar y personalizar.
  • Herramientas y tecnología: Las herramientas evolucionan, por lo que importa es que sus usuarios tengan la habilidad para sacarles partido.

Lo que sabemos y lo que nos queda por descubrir


No existe la visualización perfecta y por ello se trata de adecuar las técnicas que conocemos al caso que se nos presenta. Ese grado de adecuación puede ser automatizado hasta un cierto grado, para convertirse en parte de una metodología, o más aún de un algoritmo.

Pero en cuanto el número de dimensiones de los datos aumenta, las posibilidades también lo hacen, y es cuando más importante resulta mantener el foco en lo que estamos intentando comunicar, sintetizar, responder.

Read more »

dic. 15
2013

Enlaces de interés 2013-50

dic. 12
2013

Predecir disturbios con modelos matemáticos

Vía flowingdata leí hace meses que un grupo de investigadores han analizado los disturbios de Londres en 2011, para destilar un modelo matemático de predicción de tales disturbios.

Aunque se pone hincapié en la parte matemática del estudio, hay que destacar también la base teórica de ciencias sociales que se aplica para dar cuerpo a ese modelo. En este caso, la sociología permite acotar el enfoque del modelo y darle más sentido.

Para resumir algunos de los puntos interesantes:

  • La distancia a la que se desplazan los responsables de los disturbios sigue el mismo modelo matemático que la distancia que recorren compradores para ir a los centros comerciales. Esto explica el por qué algunas áreas de las ciudades quedaron prácticamente devastadas mientras que otras se mantuvieron intactas.
  • El proceso de los disturbios es iterativo, y responde a un esquema de presa-depredador, por lo que a mayor presencia de policía menores disturbios, que a su vez se dispersan por otras áreas.
  • El aumento de masa crítica de participantes en los disturbios tiene un comportamiento viral, potenciado especialmente por los mensajes de texto.
  • La semilla para que todo este proceso surja y crezca hay que buscarlo en zonas con altos niveles de pobreza y paro, a la vez que con déficit de escolarización.


En el siguiente video se puede ver una explicación de Hannah Fry,  coautora del estudio. Creo que salvo en la parte final de la explicación, está muy centrado en explicar cómo el modelo puede ser de utilidad para la policía, y poco en explicar cómo las causas originales de los disturbios inciden en su proliferación. Pero al fin y al cabo, lo primero es el objeto del estudio.

Read more »

dic. 11
2013

Magento: cómo iterar más agilmente sobre una colección extensa de modelos

Una de las primeras cuestiones que se encuentra un programador en Magento es que es necesario ser estricto en el uso de los recursos (memoria y CPU), ya que en caso contrario es fácil quedarse sin memoria.

Una de las situaciones típicas en este proceso son el manejo de colecciones de productos.  La carga de una página de categoría que contenga una docena de productos no es un problema, pero sí lo es cuando queremos procesar centenares o miles de productos en bloque.  En ese caso, no es extraño acabar viendo un mensaje como éste:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 49 bytes) in ... on line ...


La primera reacción, la más natural, es aumentar la memoria. Pero eso no es una solución ni ayuda a entender el funcionamiento de Magento. Además, lo que hoy son 128 MB, mañana es el doble, y así va creciendo.

Uso de Mage::getModel()->getCollection()


La forma clásica en Magento de recopilar un conjunto de modelos es utilizando getCollection(), para luego definir los atributos a recuperar, los filtros de la consulta, joins, el límite y el offset. Más sobre esto en otro artículo.

Finalmente, se realiza la llamada al método load(), que es el método que ejecuta realmente la consulta contra el servidor. En ese momento tenemos todos los modelos (que son instancias de la clase modelo correspondiente) en memoria, con todo lo que ello implica:

Mage::getModel("catalog/product")
->getCollection()
->addAttributeToSelect('sku')
->setPage(1)
->setPageSize(10)
->load();

Aunque esta aproximación es factible para consultas con límites no muy largos, el incremento en el número de productos recuperados dispara el uso de memoria. Lo que sucede es que para cada ítem, Magento genera una instancia del objeto del modelo, y eso implica instanciaciones, relaciones con otras clases,  y al fin y al cabo mucha más memoria de la necesaria para lo que ocupan los datos.

Uso del iterador


Por suerte para los que no siempre necesitamos ese volumen de información, Magento proporciona el Resource Iterator. El archivo implicado se encuentra en app/code/core/Mage/Core/Model/Resource/Iterator.php, y podrás ver que es bastante sencillo. En concreto, el método que nos interesa (walk) contiene el siguiente código:

    public function walk($query, array $callbacks, array $args=array(), $adapter = null)
{
$stmt = $this->_getStatement($query, $adapter);
$args['idx'] = 0;
while ($row = $stmt->fetch()) {
$args['row'] = $row;
foreach ($callbacks as $callback) {
$result = call_user_func($callback, $args);
if (!empty($result)) {
$args = array_merge($args, $result);
}
}
$args['idx']++;
}
return $this;
}

Lo que hace este método es cargar la lista de modelos de la colección, uno por uno, y para cada cual ejecuta la (o las!) $callbacks que se han enviado.  A cada una de las callbacks se le envía la lista de argumentos $args.

Ojo también al detalle en el interior if (!empty($result)) {...}, porque es interesante.  Si enviamos más de una función de callback, la segunda función puede recibir el valor retornado por la primera, y la tercera lo retornado por la segunda, y así hasta el final.  Esto nos permite trabajar en operaciones muy atomizadas (como siempre, sin abusar).

También es interesante comprobar que el contenido recuperado de la base de datos se añade al array $args dentro del índice 'row', por lo que los datos retornados del registro estarán en $args['row'].  También es interesante darse cuenta que los datos recuperados por fetch ya no son un objeto, sino un Array, por lo que todo lo que rodea al objeto modelo queda al margen de esta operativa.

Bueno pues, dicho esto, ¿cómo llamamos al iterador? Con una pequeña diferencia respecto a antes: dejamos de lado load() y utilizaremos getSelect(). Tomando como base la consulta anterior, puedes quitar los límites

$productos = Mage::getModel("catalog/product")
->getCollection()
->addAttributeToSelect('sku');

Mage::getSingleton('core/resource_iterator')->walk($productos->getSelect(), array('funcionCallback'), array('arg1' => 'nombredemitienda', 'arg2' => 'idioma de la tienda', ...));

Bien, entonces ¿ya estamos? No. Es necesario disponer de la función funcionCallback, que es a la que se llamará para cada producto.  Esta función debería tener la forma siguiente y puede tener una forma tan sencilla como:

function funcionCallback($args) {
print_r($args);
}

Com esto puedes ver el contenido de la matriz $args.

Pero por lo comentado arriba, podemos enviar más callbacks, y también podemos enviar callbacks a métodos de este objeto u otros.  Para cada caso, las llamadas serían:

  • Una llamada a un método del propio objeto: array(array($this, 'nombreDelMetodo'))
  • Varias llamadas a métodos del propio objeto: array(array($this, 'metodo1'), array($this, 'metodo2))
  • Combinación de llamadas a métodos y a funciones básicas: array('funcionExterna', array($this, 'metodo1'), array($this, 'metodo2))

Comprobación de las diferencias


Al ejecutar un proceso de recorrido por los modelos de una colección podrás experimentar dos diferencias notables:

  • El volumen de memoria se mantiene estable, que es algo que no siempre sucede cuando se cargan instancias de la clase modelo (más sobre la gestión de memoria en PHP en otro momento).
  • Si no es necesario que instancies un objeto (del producto que estás iterando) dentro de las funciones de callback, vas a notar que la velocidad de proceso se dispara en uno o dos órdenes de magnitud. Esto no siempre es posible, porque a veces es necesario guardar los cambios en el producto, pero si consigues evitarlo, verás que la mejora es impresionante.


 

 

Read more »

© 2007 and beyond Mario Alberich, licensed under CC-BY-SA unless stated otherwise.