Viendo videos de Youzee en Linux

Youzee LogoPara los despistados, Youzee es una nueva plataforma web (creada por iniciativa española, aun en fase beta) para la visualización de películas y series de forma extremadamente cómoda. Eso sí, pagando una cuota de unos 7 € mensuales. A mi parecer, el coste puede valer la pena, el catálogo es grande (y sigue creciendo), la calidad de streaming es alta y los films y series están disponibles en varios idiomas.

Aunque no es la única plataforma de este estilo (tenemos por ejemplo a Hulu, Netflix, que desgraciadamente no aterrizará en nuestro país, u otras iniciativas españolas como Wuaki.tv) tengo que admitir que hasta el momento es la que más me ha gustado... salvo por un detalle: Hubo problemas con los monitores VGA, y en especial con Linux (pero tengo la sensación de que lo mismo debe pasar con las otras plataformas estadounidenses).

Por suerte los problemas iniciales se han ido solucionando, y el de Linux se puede sortear con un pequeño apaño. Bastará con instalar el paquete hal con la herramienta aptitude o apt-get (o synaptic, o la que prefiráis vosotros).

Hay un detalle que conviene comentar para los usuarios de Ubuntu. Parece que la forma en que se instala el plugin Adobe Flash puede hacer que la cosa funcione o no. En particular recomiendo instalar el paquete adobe-flashplugin en vez del paquete flashplugin-installer. Además es conveniente señalar que la herramienta aptitude puede ser problemática para instalar el paquete adobe-flashplugin, por lo que es preferible usar apt-get.

Referencias

  1. http://blog.guiloma.es/2012/01/usando-youzee-en-linuxdebianubuntu.html

Se alínean los planetas para Linux

TuxEste será un breve apunte en el que esbozaré el por qué creo que últimamente le están yendo bien las cosas a todo el mundillo de Linux. La verdad es que últimamente no paro de ver buenos augurios allí donde poso la mirada: parece que los planetas se han alineado para el sistema del pingüino :) .

Aunque la noticia ya tiene más de un mes, la usaré como punto inicial de mi argumentación. Hace poco corrió por la red el rumor de que Linux había alcanzado una cuota de mercado del 1.41%, aunque pocos más han vuelto a escribir algo al respecto, un mes después podemos decir que se ha alcanzado el 1.56% (al menos según uno de los muchos barómetros existentes). Aunque soy consciente de que las medidas son falibles y que además hay quienes las contradicen con otros datos, quiero recalcar el hecho de que incluso si los números estuvieran mal, es muy probable que no lo estén tanto las tendencias representadas (en términos cualitativos).

Mi predicción es que la tendencia de crecimiento continuará, como mínimo, hasta finales de mayo. Y me apoyo en las siguientes premisas:

Tendremos que esperar para ver si me equivoco o no, a mediados o finales de mayo me podréis dar la vara si he pecado de optimista. Creo que hasta me atreveré a dar números: a finales de Abril se habrá llegado como mínimo a un 1.9% de uso (al menos con ese indicador). Para acabar, hay aun un factor que no he considerado todavía ¿qué pasaría si en esta crecida se consigue alcanzar la "masa crítica" que permita alargar el crecimiento unos cuantos meses más?

¿Y vosotros qué opináis?

Mejorar eficiencia en peticiones AJAX

JSON logoLa mayoría de desarrolladores de aplicaciones web desean que éstas sean usadas por miles de personas (y si es a la vez, mejor). Cuando se llega a un determinado número de usuarios, es difícil que la aplicación aguante esa carga si no se han tomado ciertas decisiones. La más simple (y probablemente más cara) pasa por añadir más prestaciones a los servidores con los que trabaja nuestra app, pero evidentemente podemos encontrar soluciones ligeramente mejores.

Hoy en día es extraño encontrar una aplicación web que no haga uso de AJAX, unas lo hacen de manera inteligente y otras no tanto. Vamos a ver qué podemos hacer para reducir un poco(en caso de no haberlo hecho ya) la carga que deben soportar nuestros servidores.

El consejo básico es simple: es preferible que el contenido dinámico sea generado en el lado del cliente con Javascript a que el trabajo lo hagan nuestras máquinas. Es claro que no siempre se podrá hacer eso, pero por lo general sí, como ejemplo tenemos datos que se actualizan periódicamente o que se estructuran de forma tabular o en listados.

La justificación del consejo radica en 2 puntos, en primer lugar podemos reducir el tiempo de CPU en el servidor consumido por petición, en segundo lugar podemos reducir el ancho de banda usado si enviamos datos como JSON en vez de contenido HTML pregenerado. Así dicho suena creíble, pero tenemos que comprobarlo (me fijaré en el caso concreto de PHP).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
 
// Codigo que sirve petición con JSON
$link = mysql_connect('xxx', 'xxx', 'xxx');
 
mysql_select_db('xxx');
 
$dbresult = mysql_query('SELECT nick, passwd, name FROM json');
 
$outresult = array();
 
while ($outresult[] = mysql_fetch_row($dbresult));
array_pop($outresult);
 
echo json_encode($outresult);
 
mysql_close($link);
 
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
 
// Codigo que sirve la petición con HTML
 
$link = mysql_connect('xxx', 'xxx', 'xxx');
 
mysql_select_db('xxx');
 
$dbresult = mysql_query('SELECT nick, passwd, name FROM json');
 
while ($row = mysql_fetch_row($dbresult)) {
    echo '<tr><td>',$row[0],'</td><td>',$row[1],'</td><td>',$row[2],'</td></tr>';
}
 
mysql_close($link);
 
?>

Antes de hablar sobre como se procesa la petición en el lado del cliente haré algunas observaciones. Aunque en este código no está, añadí código para medir cuantos milisegundos tardaba cada script en ejecutarse. Para aumentar la fiabilidad de las pruebas conté solo el tiempo que se tarda en procesar el resultado de la consulta a la base de datos y enviarla. Así pues excluyo el acceso a la base de datos y el cierre de la conexión de las medidas efectuadas, que son las siguientes (había 200 registros en la base de datos):

  • Petición servida en JSON (10 muestras):
    • Número de bytes enviados: 18830
    • Pico de memoria consumida: 305128 bytes ~ 297.976 Kb
    • Tiempo mínimo: 0.62799 ms
    • Tiempo máximo: 1.2610 ms
    • Tiempo medio: 0.9064 ms
    • Desviación típica: 0.1436 ms
  • Petición servida en HTML (10 muestras):
    • Número de bytes enviados: 23854
    • Pico de memoria consumida: 100008 bytes ~ 97.664 Kb
    • Tiempo mínimo: 0.7529 ms
    • Tiempo máximo: 2.4579 ms
    • Tiempo medio: 1.2909 ms
    • Desviación típica: 0.4956 ms

Lo más destacable de estas medidas es el número de bytes enviados, con JSON podemos ahorrar (como mínimo) un 21.06% de ancho de banda. Digo como mínimo porque en este ejemplo el código HTML generado es más bien austero, ya que no incorpora clases CSS ni identificadores para facilitar el manejo del DOM.

El segundo dato nos muestra la cantidad máxima de memoria consumida durante la petición procesada. Como era esperable, la primera versión del código consume más memoria debido al array que va construyendo y a la cadena JSON que ensambla finalmente a partir de la lista generada. En este punto hay que tener en cuenta que, si somos listos, esto no tiene por qué suponer un gran problema ya que ese mismo array podríamos (y de hecho es recomendable) guardarlo usando (por ejemplo) Memcached de forma que ahorramos posteriores consultas a la base de datos.

Respecto a los otros datos tengo que decir que no son significativos en lo tocante al asunto JSON vs HTML, pues la comparativa no es del todo justa. Sin embargo, lo que sí podemos ver es qué supone usar repetidas veces la primitiva echo frente a un solo uso. Por un lado aumentan los tiempos de ejecución, y por otro aumenta la dispersión de las medidas (ver desviación típica), lo que puede tocar un poco las narices cuando queremos hacer cálculos de cara a escalar nuestra infraestructura.

Otra versión del código que genera HTML es la siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
 
$link = mysql_connect('xxx', 'xxx', 'xxx');
 
mysql_select_db('xxx');
 
$dbresult = mysql_query('SELECT nick, passwd, name FROM json');
 
$outresult = '';
 
while ($row = mysql_fetch_row($dbresult)) {
    $outresult .= '<tr><td>'.$row[0].'</td><td>'.$row[1].'</td><td>'.$row[2].'</td></tr>';
}
 
echo $outresult;
 
mysql_close($link);
 
?>

Los datos que arroja esta versión son los siguientes:

  • Petición servida en HTML (2ª versión, 10 muestras):
    • Número de bytes enviados: 23854
    • Pico de memoria consumida: 126432 bytes ~ 123.469 Kb
    • Tiempo mínimo: 0.3531 ms
    • Tiempo máximo: 0.8111 ms
    • Tiempo medio:  0.5435 ms
    • Desviación típica: 0.1577 ms

Podemos extraer algunas conclusiones más de esta tercera lista de cifras. En primer lugar se nos podría ocurrir adoptar el mismo enfoque para la generación de JSON, es decir, olvidarnos de construir un array y pasar a construir un string directamente (de hecho obtendríamos mejores resultados, pues la cadena JSON es más corta que la cadena HTML). Si no vamos a usar más esos datos en un lapso de tiempo breve parece lo más acertado, pero si tenemos planeado acceder a ellos otra vez puede que sí nos convenga construir la lista como en el primer ejemplo de código.

Un detalle interesante es que teniendo un array probablemente sea más rápido generar un texto JSON con la función json_encode que concatenando strings en un bucle. El problema que tenemos (en este caso) es que el driver nativo de MySQL para PHP no permite obtener una lista con todas las filas directamente, y consecuentemente nos vemos forzados a construirla nosotros (que es menos eficiente que usar un método nativo de PHP programado en C, y de ahí que el tercer ejemplo rinda mejor que el segundo).

Tengo que admitir que no conozco por qué no hay un método nativo de PHP para obtener en forma de array todos los resultados de una consulta a una base de datos MySQL, pero creo que, en caso de no haber razones de peso... puede ser una buena jugada implementar en C una extensión del lenguaje que haga precisamente eso para ahorrar un valioso tiempo de ejecución.

En el lado del cliente las diferencias no han sido estadísticamente significativas para mi ejemplo, aunque es de esperar que los tiempos de descarga sean menores con JSON, mientras que los de proceso sean menores con HTML. El tiempo total dependerá de la potencia de cómputo del cliente y del ancho de banda de la conexión, por lo que algunos usuarios saldrán beneficiados mientras que otros puede que tarden algunos milisegundos más en obtener la página web completamente renderizada.

Sin más rodeos, resumen rápido: JSON permite reducir el ancho de banda consumido en más de un 21%, hacer un solo echo reduce el tiempo de ejecución (la reducción puede sobrepasar fácilmente el 50%, en el caso del ejemplo es un 57.89%) y la dispersión estadística de esos mismos tiempos (lo que nos puede ayudar a realizar mejores cálculos para escalar la plataforma o puede servir para que los balanceadores de carga tengan datos más fiables con los que trabajar).

Como apunte final solo quiero destacar que es importante realizar experimentos y comprobar los hechos por uno mismo, pues la tecnología evoluciona constantemente y es probable que ciertas afirmaciones no se puedan sostener en el tiempo. Además me he dejado algunas técnicas en el tintero, como usar los métodos ob_start y ob_end_clean, que nos permiten aprovechar el buffer de escritura para evitar la necesidad de concatenaciones. Supongo que viendo la extensión del artículo comprenderéis que no lo haya comentado en profundidad. Espero que os haya sido útil :) .