miércoles, diciembre 05, 2007

Problemas de memoria (y algunas soluciones)

Gracias a Lambda The Ultimate he encontrado un artículo muy ilustrativo sobre el típico flame de gestión automática de memoria contra gestión manual: Quantifying the Performance of Garbage Collection vs. Explicit Memory Management de Matthew Hertz, Yi Feng, Emery D. Berger. Si hacemos caso de sus conclusiones:

Si las aplicaciones se ejecutan en sistemas con al menos tres veces más memoria RAM de la necesaria entonces la recolección de basura proporciona un rendimiento razonable. Sin embargo si el sistema dispone de menos RAM o las aplicaciones tienen que competir con otras por memoria entonces se debe esperar que la recolección de basura traiga consigo un coste de rendimiento sustancial.
Como es sabido, no es blanco ni negro, sino que es una cuestión de compromisos, pero al menos ahora tenemos algún dato para tomar la decisión. De todos modos el artículo tiene más cosas que esta conclusión: compara diversas estrategias de recolección de basura y tiene muchas referencias interesantes.

A raíz de una de esas referencias me he encontrado con un asignador de memoria dinámica (allocator): hoard, curiosamente desarrollado por Emery Berger, uno de los autores del artículo anterior. Este asignador promete evitar uno de los grandes cuellos de botella de la programación con threads y sistemas multicore: la gestión de la memoria dinámica, el heap. Citando también del primer artículo:

En particular, las versiones recientes de hoard mantiene en el espacio local del thread la lista de los espacios libres (freelist) y usa generalmente operaciones atómicas sólo cuando se sincronizan o se rellenan.
Muy interesante...

Problemas de memoria (y algunas soluciones) en barrapunto

jueves, noviembre 29, 2007

Recursos para optimizar programas en C++ y ensamblador

Ya se sabe, la optimización prematura es la raíz de todo mal. Pero hay veces que es necesario optimizar y en estos casos no viene mal una ayuda... Por un lado conocer la estructura de las arquitecturas modernas de uso común en cuanto a memoria y cachés. De eso ya se ha encargado Ulrich Drepper como hemos comentado hace poco por aquí.

Por otro lado, he encontrado gracias a programming.reddit una serie de recursos entre los que se encuentran documentos en pdf que podrían ayudarnos. Todos ellos están escritos por Agner Fog y están reunidos en Software optimization resources. Son bastante extensos y por lo que he ojeado con bastante información valiosa. De ellos destacaría (es el que más he mirado), Optimizing software in C++ (An optimization guide for Windows, Linux and Mac platforms) (pdf) que repasa formas de optimizar C++ reparando además en particularidades de plataformas y compiladores.

Además hay también una guía para para optimizar ensamblador para plataformas x86, tablas con características de las instrucciones de Intel y AMD, programas de test y más enlaces. A disfrutar con la lectura, pero a usar con precaución ;)

Recursos para optimizar programas en C++ y ensamblador en barrapunto

jueves, noviembre 22, 2007

jueves, noviembre 08, 2007

Programando con threads: algunos enlaces

Algunos enlaces a tener en cuenta si programas con threads: Programando con threads: algunos enlaces en barrapunto

jueves, octubre 18, 2007

El programador (una apología)

Me apetece hacer apología del puesto de programador, porque creo que es necesario por dos motivos fundamentales y relacionados: no se le considera un puesto apetecible por ser jerárquicamente bajo y no se tiene conciencia de que la experiencia en la programación sea útil. En resumen, que el puesto de programador no se considera de futuro[1]. Pero no es el futuro profesional del programador[2] de lo que quiero hacer apología, sino de la labor del programador en si: difícil pero necesaria y apasionante[3].

Los buenos programadores son imprescindibles para que este mundo funcione. En la eterna, manida y estéril discusión de las atribuciones profesionales se suele denostar la labor de programador en favor de la figura del arquitecto de software. No voy a entrar aquí en lo importante de una buena dirección y coordinación en un proyecto de desarrollo (que lo es), sino de lo importante que es el trabajo de base. Porque el de programador en un puesto intrínsecamente bajo desde el punto de vista jerárquico. ¿Significa eso que es un trabajo rutinario, sin retos ni creatividad? En absoluto. Es un trabajo muy decisivo, a veces creativo y de gran responsabilidad casi por definición.

Es difícil porque hacer software es intrínsecamente difícil[4][5] Y el creer que toda la dificultad se puede abstraer del programador hacia arriba en la jerarquía no deja de ser una especie de pensamiento mágico alejado de toda realidad. Es prácticamente imposible hacer un análisis y diseño completos sin resquicios y teniendo en cuenta todos los detalles del sistema final, tanto funcionales como de rendimiento y seguridad. Es muy frecuente que aparezcan aspectos dependientes de que la implementación sea óptima y adecuada al uso del sistema final.

Es de una gran responsabilidad porque, entre otras cosas, es muy fácil hacerlo mal y no es trivial descubrirlo[6]. El programador moldea con sus manos el sistema final que va estar funcionando, transforma en realidad, en funcional, un concepto ideal. Y es el que más directamente que se da de bruces con las limitaciones del mundo real, de las herramientas y los sistemas. Es el que, si es brillante, es capaz de dar soluciones a esas limitaciones o al menos no acrecentarlas. Pero un programador no muy hábil o simplemente poco disciplinado o descuidado puede provocar errores, tanto fáciles de detectar como demasiado sutiles para ser detectados cuando deben, en la fase más temprana posible del desarrollo.[7]

Tengo que decir que lo que yo entiendo por programador es lo que a veces se denomina "desarrollador", algo un poco más amplio que solo tirar líneas, pero me niego a renunciar a usar el término: me gusta decir programador, me gusta programar.

[1] Y es posible que no lo sea :( Me gustaría pensar que, por lo que cuento después, lo es.
[2] Bueno, hay muchos futuros dentro del desarrollo. Uno, ascender. Otro, especializarse. Pero bueno del futuro profesional prefiero que hablen los comentaristas...
[3] Obviamente hay mucho que comentar de los aspectos sociales del programador, que pueden condicionar, pero no hablaré de ellos. Para saber más pasa por aquí ( bueno, o por aquí)
[4] "The complexity of software is an essential property, not an accidental one. Hence, descriptions of a software entity that abstract away its complexity often abstract away its essence" No silver Bullet, Frederick P. Brooks
[5] Un poco más actual: Software Is Hard, Kyle Wilson
[6] Me gusta mucho la frase de Brian Kernighan: "Depurar es el doble de difícil que escribir el código por primera vez. Entonces, si escribes código tan inteligentemente como te sea posible, no vas a ser, por definición, suficientemente listo para depurarlo" Depurar es otra habilidad quizás no demasiado valorada del programador experto.
[7] Metodologías de desarrollo y/o testeo adecuadas y acordes con el proyecto aceleran la caza de errores, pero la disciplina y experiencia del programador son la base del desarrollo de calidad.

"El programador (una apología)" en barrapunto

miércoles, octubre 10, 2007

¿Está acabando internet con el contenido extenso?

Se suele recordar mucho últimamente que el vídeo mató a la estrella de la radio por aquello del cambio de formato y de la (no) adaptación de la industria musical a esos nuevos formatos. Lo mismo seguramente se puede ampliar al resto de los contenidos culturales, en el amplio sentido de la palabra, y sobre todo al libro ¿Mató internet el contenido extenso? ¿Mató internet a los libros?

El caso es que últimamente he visto varios casos en los cuales el modo de publicación es controvertido porque se trata de contenidos de un volumen grande, más grande que un post de blog, para entendernos. Primero fue Ulrich Drepper que dudó que opción tomar y tomó la resolución de publicarlo por partes en LWN. Ian Lance Taylor ha publicado un número enorme de post, veinte, muy interesantes (para mi al menos ;) ) sobre enlazadores, pero demuestra claramente que el blog no sirve para crear contenidos amplios y legibles a la vez.

¿Cual es la tendencia? Hemos visto decaer sitios de generación y promoción de contenidos que premiaban calidad y extensión, como k5 o libertonia. Triunfan sitios del tipo digg, reddit o meneame en los que sólo se hace referencia y se extracta brevemente. No se me entienda mal, los sitios me parecen útiles, programming.reddit y tecnologia.meneame los visito y uso. Pero creo que tienden a ser autocontenidos, a quedarse más en si mismos que a servir para lo que probablemente deberían servir: promocionar contenido de calidad. Es la tendencia al minimalismo, tanto en la referencia como en el comentario: estos sistemas premian la brevedad y la concisión, con buenas razones, pero en perjuicio de contenido espeso y en favor del impactante. /. en las dos versiones que uso estaría a medio camino, pero no se acaba de librar de este mal... Es el signo de los tiempos, en los que la sobrecarga informativa va acompañada de atención parcial continuada...

Pues bueno, Charles Petzold, que escribe mucho mejor que yo y que además tiene un buen curriculum de libros espesos publicados reflexiona sobre ello en Hard Work, No Pay: What's the Point?, teniendo en cuenta que lo hace, al menos en parte, desde el punto de vista de un autor. Se pregunta ¿por qué libros y no entradas en blogs? Y responde (citraduzco un poco al vuelo)

Es fácil convencerse de que los pedacitos de prosa representan el nivel óptimo de granularidad de información. Es parte de la visión utópica de la web como una plétora de páginas débilmente enlazadas cuya sinergia genera toda la información que necesitamos. Esta ilusión está afectando a la manera en la que aprendemos y tengo miedo de que no tengamos una visión más amplia y completa que solo un libro puede proporcionar. Un buen autor encontrará una selva poco manejable de información y cortará una senda coherente para pasar a través de ella, a través de una narrativa que enlaza el material.
Respuesta que me ha gustado mucho porque ilustra muy bien el tipo de libros que deberían sobrevivir a la mencionada sobrecarga informativa: aquellos que son capaces de establecer un poco de orden y hacer un poco más comprensible la realidad fragmentada.

¿Está acabando internet con el contenido extenso? en barrapunto

jueves, octubre 04, 2007

Lo que todo programador debería saber sobre la memoria

Así titula Ulrich Drepper un artículo sobre los posibles cuellos de botella que se generan en las arquitecturas modernas de uso común, explicando el comportamiento de las caches de CPU, el diseño de los controladores de memoria, el DMA... Debería ser útil para esos momentos en los que las abstracciones que usamos empiezan a fallar y debemos conocer lo que hay debajo.

El modo de publicarlo es un poco, bueno, llamémosle arcaico, pero nos conformaremos porque el contenido lo merece, y porque es el deseo del autor, claro... El caso es que se va a publicar por partes en LWN.net y al comienzo serán accesibles solo para suscriptores y posteriormente para el resto. Al final publicarán la versión pdf que probablemente será muy interesante para imprimir. Actualización (22/11/07): Ya está disponible la versión en pdf: "What Every Programmer Should Know About Memory" por Ulrich Drepper

He ido actualizando esta entrada conforme se han liberado las todas las partes del documento, muy interesantes:

Bonus Track: Como creo que pega en esta entrada, pongo el link a unas charlas con diapositivas de Herb Sutter sobre temas similares: Machine Architecture: Things Your Programming Language Never Told You (jejeje, Sutter y Drepper ¿lo mejor de los los dos mundos?)

Lo que todo programador debería saber sobre la memoria en barrapunto

martes, octubre 02, 2007

Paul Graham Facts

Paul Graham Facts. Sólo apto para quien sepa quien es Paul Graham (bueno, y aún así...) Ejemplo: Paul Graham is so good, he always tips using $2.56 cheques made out by Donald Knuth

Actualización: por si alguien es tan masoquista de quedarse con ganas de más: Bruce Schneier Facts. Espero que me sepan perdonar :)

Paul Graham Facts en barrapunto

lunes, septiembre 24, 2007

Intel anuncia un compilador con memoria transaccional

Intel está trabajando en un compilador que gestiona memoria transaccional y que está ya en estado de prototipo. Al parecer se puede descargar y usar y para hacernos una idea ponen un miniejemplo de uso. Parece que esta tecnología está saltando de la investigación académica a la industria, habrá que ir viendo lo que da de si, porque, como ya comenté por aquí, hay gente que no acaba de verlo claro.

Intel anuncia un compilador con memoria transaccional en barrapunto

viernes, septiembre 21, 2007

¿Necesitan una reescritura las bases de datos relacionales?

Hoy en High Scalability enlazan a un artículo que 'denuncia' la obsolescencia del diseño e implementación de las actuales bases de datos relacionales: The End of an Architectural Era (It’s Time for a Complete Rewrite). Con una implementación que tiene en cuenta las arquitecturas actuales con sus cuellos de botella en cuanto a CPU, memoria y recursos de red, como ajustar el tamaño de los árboles-B al tamaño de la caché L2 o hacer los procesos de consulta en cada nodo con un solo hilo han conseguido rebajar hasta en dos órdenes de magnitud en el test TPC-C.

Este artículo forma una serie con “One Size Fits All”: An Idea Whose Time Has Come and Gone y One Size Fits All? – Part 2: Benchmarking Results en los que resalta no solo que el diseño y la implementación de los RDBMS son algo obsoleto sino que no son lo más adecuado para todos los escenarios (como ya se han dado cuenta los que se han encontrado con el problema)

Y ya un poco offtopic en este tema me gustaría resaltar una frase:

In the programming language community, there has been an explosion of “little languages” such as Python, Perl, Ruby and PHP. The idea is that one should use the best language available for any particular task at hand. Also little languages are attractive because they are easier to learn than general purpose languages. From afar, this phenomenon apears to be the death of “one size fits all” in the programming language world
O sea que en el futuro se llevará el programador políglota (bueno, o no, depende de quien mande...)

¿Necesitan una reescritura las bases de datos relacionales? en barrapunto

jueves, septiembre 06, 2007

Sam Ruby y Erlang

Asisto con una mezcla de envidia y escepticismo a la conversión a Erlang de Sam Ruby. Sam Ruby es un típico goleor tecnológico ™ Siempre está a la última en cuanto a estándares y lenguajes sobre la web. De hecho, algunos los hace él :) Como buen experimentador de tecnología, como buen gurú, hace sus apuestas de futuro. La última apuesta de Ruby, muy interesante, es a varias bandas: REST, Hadoop, Erlang/OTP y los Microformatos.

Asisto con envidia sobre todo por la fase de enamoramiento compulsivo por la que está pasando (muy interesante para los demás, por cierto) con Erlang, aunque resulta extraña en alguien con tanta experiencia como él. Sino no se puede explicar que diga, en su última entrada, algo tan bonito como:

Con muchos frameworks y lenguajes, tengo la sensación de que estoy trabajando con un armario de metal con capas de pintura para barcos; cuando se le hace un rasguño salen a relucir los bordes afilados. Con Erlang tengo la sensación de un armario victoriano de caoba; cuando uno raya en la madera simplemente sale a relucir más valiosa madera.

Pero este enamoramiento nos está dando a los demás la posibilidad de seguir sus pasos y disfrutar de su código, que no está nada mal... El último paso ha sido un conversor de Atom a JSON, pero anteriormente ha hecho alguna cosita más, como envíar XHTML-IM sobre TLS con Erlang y una pequeña entrada sobre Comunicación entre procesos en Erlang. A ver si dura :)

Sam Ruby y Erlang en barrapunto

miércoles, agosto 08, 2007

La humildad como virtud del programador

Y no me refiero a modestia frente a los otros (que también puede ser una buena cualidad) sino humildad con uno mismo y con lo difícil de hacer realmente bien este trabajo. En este sentido, sin más, le cedo la palabra a Jonathan Edwards, quien en Beautiful Code dice:

Una lección que he aprendido por la vía difícil es que no somos lo suficientemente listos. Incluso los programadores más brillantes cometen errores estúpidos con frecuencia. No solo errores de tecleo (typos) sino errores básicos de diseño que ponen en una situación difícil al código, y que a posteriori deberían haber sido obvios. La mente humana no es capaz de comprender en su conjunto la complejidad de un programa de tamaño moderado, mucho menos los sistemas monstruosos que construimos hoy en día. Esta es la amarga pastilla que nos tenemos que tragar, porque programar atrae y recompensa al inteligente, y su cultura fomenta la arrogancia intelectual. Me ha ha sido de inmensa ayuda trabajar con el supuesto de que soy demasiado estúpido para hacer las cosas correctamente. Esto me hacer usar de modo conservador aquello que ha funcionado, testear cautelosamente las nuevas ideas antes de confiar en ellas y por encima de todo, apreciar la simplicidad.
Curiosamente habla de un libro que me gustaría mucho adquirir y cuya existencia comenté por aquí.

Sobre el mismo tema, me gustaría recordar una famosísima cita de Brian Kernighan:

Depurar es el doble de difícil que escribir el código por primera vez. Entonces, si escribes código tan inteligentemente como te sea posible, no vas a ser, por definición, suficientemente listo para depurarlo.

Actualización: Creo que no ha quedado claro (he escrito la entrada demasiado rápido), pero lo que me parece curioso del comentario de Jonathan Edwards, es que es una justificación de porqué no escribió en Beautiful Code a pesar de estar invitado para ello, con una explicación tan inspirada que irónicamente merecería estar en el libro... :)

La humildad como virtud del programador en barrapunto

lunes, agosto 06, 2007

Varios sobre concurrencia: JVM, clasificaciones y consejos

Una ración de enlaces relacionados con la programación concurrente:

Varios sobre concurrencia: JVM, clasificaciones y consejos en barrapunto

jueves, julio 26, 2007

Un vistazo a Threading Building Blocks

Según se puede leer en Ars technica: Intel open sources multicore programming tool Intel libera Threading Building Blocks, una herramienta hasta ahora propietaria que ayuda a la programación concurrente. La noticia ha salido en muchos sitios con comentarios interesantes (Slashdot, OSNews o en barrapunto)

Había oído hablar de esta herramienta en la entrevista a Sanjiv Shah de OpenMP en thinking parallel, pero como él trabaja en Intel siempre parece más sospechoso tratándose de un producto comercial. Ahora que lo han liberado he estado echándole un vistazo y bueno, creo que tiene su ámbito de aplicación y que puede ser muy interesante para facilitar algunas tareas sin reinventar alguna rueda.

Por analizar un poco la librería, consta como de cuatro partes:

  • Algortimos para bucles paralelos: parallel_for, parallel_reduce, parallel_while. Me ha parecido de lo más interesante de la librería porque es muy fácil de implementar y te ahorra mucha gestión. Al algoritmo se le pasa un contenedor sobre el que operar y un functor y el lo procesa en paralelo automágicamente, aunque parece ser algo parametrizable.
  • Contenedores seguros a accesos concurrentes: concurrent_hash_map, concurrent_vector, concurrent_queue. Usan internamente los bloqueos de grano fino y estructuras de datos sin bloqueos. Que bien que no haya que hacerlo por uno mismo, tiene pinta de ser complicadillo y muy fácil hacerlo mal
  • Utilidades para gestión de la concurrencia: mutexes de diverso tipo (si, recursivos también), locks, operaciones atómicas
  • Un gestor de tareas: una ayuda para programar orientado a tareas, threads más ligeros que los del sistema.

Desde que lo han hecho opensource le han asignado un domino propio, http://www.threadingbuildingblocks.org/ en el que hay bastante información. En particular el tutorial al que le he echado un vistazo es Intel® Threading Building Blocks: Tutorial

Por dar alguna nota no positiva... bueno, de momento solo soporta plataformas desde Intel Pentium 4, porteriores y compatibles, aunque en una de las FAQ del proyecto dicen que soportar todos los procesadores, sistemas operativos y compiladores es una las piedras angulares del proyecto. Veremos.

También me ha llamado la atención que dijesen (extraído del artículo de ars technica):

Java and .NET versions of TBB are currently being evaluated by Intel, and may eventually be announced. But Intel maintains that C++ is the company's priority, and it's where they'll be focusing the engineering resources that they're adding to the project.

Puede ayudar a hacer un poco más multiplataforma el código paralelizado en C++, aunque ya existen muchas librerías que lo hacen, como Boost.Thread. Supongo que estará bien usarlo cuando se necesita mucho rendimiento, una aproximación más sencilla no vale y paralelizarlo de este modo sale rápido y óptimo.

Un vistazo a Threading Building Blocks en barrapunto

lunes, julio 23, 2007

¿Testeo o corrección?

Andaba yo descubriendo otro blog, el de Andrew Koenig, cuando, a raíz de dos post suyos seguidos (uno de aserciones contra excepciones y otro sobre la depuración) he reparado en el tema... últimamente se hace mucho hincapié en el desarrollo guiado por pruebas, pero según se puede ver en el segundo post, hay veces que las pruebas, e incluso el uso, no son garantía de corrección.

Por eso es tan importante que las pruebas sean realistas. Por eso es tan importante extraer información del sistema en todas la etapas del ciclo de vida. Por eso es tan importante un buen sistema de registro del sistema. Pero sobre todo, por eso es importante pensar bien antes de codificar.

También me ha recordado uno esos principios de desarrollo polémicos: Los fallos, cuanto antes mejor (Fail Fast). Es uno de los principios en el diseño de Erlang. Como dice Joe Armstrong en una entrevista reciente:

La filosofía de Erlang fue siempre construir sistemas con un montón de procesadores baratos y permitir que fallen. No prevenimos el fallo; vivimos con él y recuperamos el sistema cuando ocurren.

Hay que recordar que se trata de fallos irrecuperables, no de casos raros dentro de la lógica del programa. Es mejor dejar claro un error fatal que tratar de continuar cuando no se puede y que se pierda el rastro de lo sucedido...

Por supuesto el título es falaz, debería haber sido Testeo y corrección y todos contentos, pero espero que se me permita el recurso :)

¿Testeo o corrección? en barrapunto

miércoles, julio 18, 2007

Leyes sobre el desarrollo de software con nombre propio

Leo en haacked un listado de leyes que tienen algo que ver con el desarrollo de software y que además tienen nombre propio. Las hay serias y las hay humorísticas o simplemente pesimistas. Entre divertido, iluminador y deprimente.

De las que más me gustan:

  • La ley de Postel: Sé conservador con lo que envías, liberal con lo que recibes. Ya hablé de ella por aquí en ¿Postel o Dracón?
  • La ley de Parkinson: El trabajo se expande hasta consumir(*) todo el tiempo previsto para él. (*)Al menos, añadiría yo ;)
  • El principio de Kerchkhoff: En criptografía un sistema debería ser seguro incluso si todo acerca del sistema es de conocimiento público excepto una pequeña cantidad de información: la clave.

Habla también de las típicas leyes de estos casos, Murphy, Pareto, Sturgeon, Brooks...

Actualización: Joey deVilla inspirado en el post anterior ha hecho una recopilación francamente impresionante de leyes o dichos referidos al desarrollo del software.

Leyes sobre el desarrollo de software con nombre propio en barrapunto

martes, julio 17, 2007

Beautiful Code

El bloguerío de esto de la programación anda revuelto por la publicación de un libro que parece muy interesante Beautiful Code: Leading Programmers Explain How They Think. Y es extraño que ande tan revolucionado sin una causa económica (al parecer lo que se saque con este libro irá a AI) pero viendo los autores quizás sea para tanto; que me suenen: Brian Kernighan, Tim Bray, Charles Petzold, Diomidis Spinellis, Douglas C. Schmidt, Yukihiro Matsumoto... aunque seguro que me dejo a alguien importante :) Cinco de ellos han sido ya nombrados por aquí, que cosas...

El libro consta de 33 capítulos en los que otros tantos autores piensan en alto sobre la arquitectura de sus proyectos (o de los proyectos de otro) los compromisos que se tomaron en su construcción y cuando fue importante romper las reglas. Dado lo heterogéneo del grupo de autores seguro que hay de todo un poco, pero el tema me parece tan interesante que inmediatamente lo he puesto en mi lista de deseos de anobii, aunque creo que dentro de poco se caerá de la lista :)

Por hacerme eco de algunos de los los comentarios que ha generado, Bryan Cantrill reflexiona sobre la recursividad en el mundo real y recibe interesantes respuestas. Alberto Savoia, uno de los autores, en "Pardon My French, But This Code Is C.R.A.P." reflexiona sobre el código malo, que es mucho más abundante, parafraseando a Strurgeon ("90% of everything is crap." - Sturgeon’s Law (one of many variants) "When applied to software, Sturgeon’s Law is hopelessly optimistic." - Savoia’s Corollary to Sturgeon’s Law) y a Sartre ("Hell is other people." - J. P. Sartre "Hell is other people’s code." - T-Shirt seen recently in Mountain View, CA) :)

Beautiful Code en barrapunto

miércoles, julio 11, 2007

Varios sobre concurrencia y patrones de diseño

Ración de enlaces:Varios sobre concurrencia y patrones de diseño en barrapunto

jueves, julio 05, 2007

Artículos de Alexandrescu sobre C++

Leo a través de la sección de programación de reddit que Andrei Alexandrescu ha puesto en su página, disponibles para descarga y consulta los artículos que ha publicado en C/C++ User's Journal. Para quienes no lo conozcan, Andrei Alexandrescu es el autor de Modern C++ Design uno de los libros más influyentes y que más bien (¿y mal?) ha hecho por el C++ y sus lectores/escritores.

Me han llamado la atención especialmente Lock-Free Data Structures, Lock-Free Data Structures with Hazard Pointers y C++ and The Perils of Double-Checked Locking aunque solo sea por la introducción a la programación con bloqueos y sin bloqueos que me ha parecido hasta didáctica. También hay otros artículos sobre punteros inteligentes, constructores de movimiento y otras técnicas y temas diversos. Más para leer...

Artículos de Alexandrescu sobre C++ en barrapunto

miércoles, junio 27, 2007

El mejor código es el que no existe

Bueno, la frase es demoledora y como toda frase lapidaria, conviene matizarla. Pero contiene tanta sabiduría (pesimista o realista, tu eliges) que creo que debe convertirse en uno de los mantras a repetirse frecuentemente.

Me lo recordó hace unos días la entrada de Jeff Atwood, The Best Code is No Code At All, muy recomendable. Si, antes de codificar, de desplegar miles de millones de líneas de código hay que pensárselo muy bien. Codificar es divertido, es muy estimulante... Pero antes de empezar, antes de abrir siquiera el editor debería pasar por la cabeza, en alguna milésima de segundo, al menos alguna de estas preguntas:

  • ¿Debo escribir este código?
  • ¿Estaré reinventado alguna rueda?
  • ¿Soluciona el problema que quiero solucionar?
  • ¿Se puede hacer mejor, más compacto, más legible, solo pensando un poquito antes de teclear?

Ya decía que conviene matizar: el programa vacío no hace nada y parece que es bueno que los programas hagan algo :) Se trata de un un recordatorio ¡Cuidado con el exceso de código! Creo que no hay aberración mayor que valorar la producción por líneas de código; es como si pagaran por bugs cometidos...

Jeff cita otro artículo en el que se exhorta a comenzar con código minimalista y completarlo a través de test. Es una buena idea, pero en estos tiempos de exaltación del Test-driven development conviene recordar también que los test no lo son todo, que pararse a pensar sigue siendo imprescindible.

En resumen serás esclavo de tu código, así que piénsatelo bien ;)

El mejor código es el que no existe, en barrapunto

lunes, junio 25, 2007

AMQP ¿El nuevo Middleware universal?

Según leo en Toward a Commodity Enterprise Middleware John O'Hara en JPMorgan, harto de "el problema del Middleware" se construyó (diseñó e implementó) el suyo propio para sus sistemas: AMQP (Advanced Message Queuing Protocol)

Se basa en el paso de mensajes y su gestión, permite mensajes del tipo publicación/suscripción, guardar y reenviar o envío de ficheros, separa la capa de trasporte de la de gestión de colas, tiene un protocolo binario que lo hace menos pesado en cómputo y ancho de banda que los Servicios Web y está preparado para pasar los firewalls sin perdida de seguridad. Suena bien.

Para no cometer uno de los errores de CORBA, existe ya más de una implementación, la de referencia: OpenAMQ, otra de Apache incubator, Apache Qpid, y una última en Erlang, RabbitMQ todas ellas software libre.

Al parecer la industria está entendiendo (por fin) que el modo de hacer tecnologías interoperables es haciendo implementaciones de referencia funcionales y libres, teniendo comunidad de usuarios (y no clientes) De todos modos habrá que ver si tiene una adopción tan masiva como pretenden. Lo debería ser si efectivamente el middleware se logra convertir (ojalá) en una Comoddity

(En El auge y la caída de CORBA (y lo que podemos aprender) se comentaba que existía ICE otro prometedor middleware libre, en este caso más parecido a CORBA, según parece)

AMQP ¿El nuevo Middleware universal? en barrapunto

miércoles, junio 20, 2007

Repasando Python 3000 (o Python 3.0)

En su bitácora de Artima Guido van Rossum ha actualizado las previsiones que tiene acerca del proyecto llamado Python 3000 (que acabará siendo python 3.0)

Repasa las novedades de las versiones 2.6, que será versión puente y la 3.0. De esta última destacan el tratamiento de Unicode y entradas y salidas, el sistema de clases y tipos (con "anotaciones" que se podrán usar como tipado estático opcional), cambios en excepciones y enteros y algunos otros cambios como la eliminación de reduce() (que fue explicada en The fate of reduce() in Python 3000)

Al parecer romperá uno de los tabúes más sagrados de la informática: la compatibilidad hacia atrás, aunque habrá herramientas de conversión entre la versión 2.6 y la 3.0.

Lo comentan entre otros sitios en Lambda the Ultimate: Python 3000 Status Update, en donde, por supuesto, van a echar a faltar reduce()

Repasando Python 3000 (o Python 3.0) en barrapunto

lunes, junio 18, 2007

Errores en el diseño e interpretación de experimentos

Nota: Esto en planeta código es un poco offtopic, pero me parece lo suficientemente interesante para publicarlo en YAPW. Disculpen las molestias :)

Acabo de leer en la página de Peter Norvig una interesantísima recopilación de errores comunes en el diseño e interpretación de experimentos. Estamos demasiado acostumbrados a que se les den publicidad a determinados "estudios" que cometen algunos de los errores que Norvig repasa. Por ejemplo, hacer estudios sin una Prueba controlada aleatoria, confundir correlación con causa o mal entendimiento de la probabilidad condicionada(*) Una lectura recomendable y como decía el otro día, también de cultura general, porque afecta a la base de la metodología científica.

(*)Aunque ya comentaba Tío Petros que el ser humano parece peor equipado de lo que debería para entender intuitivamente la probabilidad, así que tenemos que hacer un esfuerzo adicional...


Errores en el diseño e interpretación de experimentos en barrapunto

jueves, junio 07, 2007

Evidencias en el desarrollo de software

Navegápolis es un blog que me gusta muchísimo. Hasta ahora no lo había referenciado porque su temática tiende más a la gestión y bueno, a mi me gusta más hablar de lo más pegado al código.

En este caso comenta Algunas evidencias del desarrollo de software extraídas directamente del libro Facts and Fallacies of Software Engineering. Haciendo una selección sobre la ya hecha por Juan Palacio:

  • El factor más importante en el trabajo con software no son las herramientas, ni las técnicas usadas por los programadores; sino la calidad de los programadores.
  • Normalmente las estimaciones se realizan al comenzar el ciclo de vida. Tiene un cierto sentido, si no fuera porque de esta forma se hace la estimación antes de definir los requisitos, y por lo tanto antes de conocer el problema.
  • La reutilización de pequeñas librerías o subrutinas llava empleándose 50 años de forma satisfactoria. La reutilización de grandes componentes es normalmente un problema sin resolver, aunque todo el mundo coincide en que es importante y deseable
  • Es 3 veces más difícil construir componentes reusables que no reusables (apunté en su día a Software Reusability: Myth Or Reality?)
  • La localización y limpieza de errores es la fase que más tiempo consume en el ciclo de vida.

Al parecer es el típico libro que, como The Mythical Man-Month, a uno le gustaría que se leyese más y en ámbitos menos técnicos. Del mismo modo a uno también le gustaría que determinadas estadísticas sobre proyectos fracasados fuesen más conocidas. Me parece de cultura general, pero debo estar equivocado :(


Evidencias en el desarrollo de software en barrapunto

lunes, junio 04, 2007

Enlaces varios (V)

Ración de enlaces que amenazaban con desbordar los marcados Keep New en bloglines, por si alguien les puede sacar utilidad:

Enlaces Varios (V) en barrapunto

viernes, junio 01, 2007

Visualizando redes sociales: amigos en Barrapunto y menéame

He hecho dos programitas que sacan las relaciones de amistad en en el interior de dos comunidades virtuales, barrapunto y menéame. Después he sacado imágenes gráficas de dichas relaciones, para visualizar, en lo posible, la compleja estructura de esas "relaciones sociales". Aunque el análisis de los datos no es muy riguroso, el resultado puede interesar tanto a los que les gusta el análisis de redes sociales online como a los que les gusta la ver programitas de ejemplo. En este caso están hechos en Erlang, y están acompañados de algún enlace que he ido recopilando en el camino.


La red social de barrapunto

Me gusta mucho ver gráficos relacionados con las ciencias que tratan de estudiar la complejidad, como los de visual complexity*, no porque sepa mucho de ello, sino como mero aficionado. El caso es que llamó mucho la atención también la representación visual de la red social de feevy (comentado por gente que sabe de esto, de entre los cuales me excluyo, en Un mar de flores).

(*Otra actualización:Parece que alguien envió esta entrada a visualcomplexity y ha sido aceptada: Social Network of barrapunto. Gracias al anónimo submitter que lo envió. Me siento muy halagado ;) )

Pues bien, el otro día se me ocurrió que se podría hacer lo mismo con los usuarios de barrapunto, que en el fondo no deja de ser una red con unas relaciones muy bien definidas: la relación de amistad y enemistad. Y también se me ocurrió que lo podría hacer con un programita que capturara esas relaciones y las dejara en formato DOT. Para ello he usado Erlang. ¿Por qué? Pues porque si. Se podía haber hecho con wget o curl y awk, y/o perl o ... Pero bueno, me apetecía hacer algo más que un Hola mundo! en este lenguaje. Y, a decir verdad, me lo he pasado muy bien programando en él y descubriéndolo.

Comentaba Alex que para visualizar la redes sociales solían usar SocNetV, pero que en este caso usó Graphviz Ambos admiten para modelar las redes el lenguaje de definición DOT. Son los programas que yo he usado para los gráficos que viene a continuación.

Primero la imagen tal cual, sin ordenar demasiado, con socnetv:



Intentando desenredar la red, estos programas tienen criterios para representar la información en función de una serie de parámetros que suelen calcularse en función del las distintas definiciones de centralidad...


Pegaré aquí las imágenes que creo que van a dar una información más interesante. Esta siguiente está generada con el socnetv, aplicando una de las ordenaciones en circulo por centralidad (en este caso, creo, "in degree centrality"):



Usando el comando nop bp.file | twopi -Tpng -o bptwopi.png, de graphviz:



La imagen que más me gusta es esta, que da alguna información de la organización, pero acercándose uno puede ver detalles (usando nop bp.file | fdp -Tpng -o bpfdp.png)... Lo malo es que subiéndola a flickr se baja tanto la resolución como la calidad. Se admiten sugerencias para subir las imágenes a un sitio donde las dejen poner a mucha resolución...Actualización: Gracias a resete-e y su cuenta de flickr pro hay imágenes de alta resolución. Muchas gracias ;)



La red social de menéame


Mientras iba haciendo el primer programa, se me ocurrió que casi por el mismo precio podría tener un segundo programa que obtuviese los datos de menéame. Solo apuntar que en este caso la red está aún más enmarañada porque hay más actores y más relaciones...

Las imágenes análogas a las anteriores serían:
(Nota: La última imagen parece en negro, pero si se pincha sobre ella sale a resolución completa...)




Los datos

Segunda actualización: No tenía donde poner los ficheros de datos, pero Eduardo de http://hombrelobo.com/ me cedió amablemente espacio, así que todos los interesados en los datos en bruto pueden jugar con ellos y con graphviz, SocNetV y con lo que quieran. Traté de embeber los svg en HTML, pero creo que no merece la pena porque son muy grandes y firefox (al menos) se queda un poco tonto. Mejor bajárselos y verlos con algún visor... Bueno, los enlaces:
Que los disfruten ;)
"Análisis"

Se ve que hay islitas, cosa que me ha sorprendido, por aquello de los seis grados de separación, pero también lo comentaba Ugarte en su entrada. Pensándolo un poco más detenidamente, tanto en este caso como en el de los enlaces feevy son casi todas relaciones fuertes en el sentido en el que se comenta en un mar de flores. No todas las relaciones débiles entre usuarios (yo leo poco a tal, yo conozco a cual, pero no le sigo) no salen en este esquema, es seguro que en ese caso todos estarían conectados... No obstante, en el caso de las gráficas de las dos comunidades, las islas son menores que en feevy, la red está más clusterizada... (este razonamiento hay que tomarlo con precaución: yo soy sólo un aficionado ;))


Más redes


Se me pasó por la cabeza un proyecto más ambicioso en en que se definiesen parámetros de búsqueda (expresiones regulares y alguna otra cosa...) pero me resultó demasiado grande para el poco uso que le iba a dar. Si alguien tiene ganas, se puede modificar muy fácilmente para sacar la red de slashdot (casi trivial) o de digg... ¿twitter? (por cierto, que alguien sacó el gráfico de los usuarios holandeses de twitter, también vía de Ugarte)



Erlang

En otro orden de cosas... lo he programado en Erlang y ha sido una gratísima experiencia. Hay quien dice que la iteración es humana, la recursión es divina, pero Erlang con su tail recursion (recusión terminal) te la facilita o más bien te la hace obligatoria para recorrer los conjuntos de datos. Pero tanto el uso de esa recursión, el manejo de listas y tuplas como la sintaxis me ha resultado muy muy natural. El hecho de que cada "sentencia" sea separada por comas, el final un punto, las flechas... todo muy intuitivo, un poco como escribir un texto, salvando las distancias ;)


Otro punto fuerte de el lenguaje es el tratamiento de la concurrencia, que es muy sencillo teniendo en cuenta una serie de premisas que ya comentó Joe Armstrong en su entrevista en Thinking parallel. Erlang no usa threads nativos sino que tiene sus propios "procesos ligeros" con lo que logra una gran escalabilidad en cuanto a número de procesos disponibles.


En este ejemplo no se observa muy bien, porque no creo que el programa lo requiriese, pero el lector atento del código podría añadirle una cierta concurrencia para hacer peticiones en paralelo, pero en este caso no es muy útil...


Aquí voy a pegar el código que he usado tal cual, con la advertencia que no es un código muy probado y tal y cual, etc, etc :)
(por cierto y a modo de recordatorio, el comando que he usado para generar el código HTML con resaltado de sintaxis es enscript --highlight=erlang --color --language=html --output=soc_graph.html soc_graph.erl)
Blogger se comió los tabuladores, los he sustituido por espacios...
El programa de barrapunto:



-module(soc_graph).
-export([do_it/0]).
-export([get_friends/1]).
-export([get_users/1]).

do_it() ->
init_file(),
get_users({self(),1}),
end_file().

%get_users gets user list
get_users({Pid,Step}) -> get_users(0,{Pid,Step}).
get_users(Pan,{Pid,Step}) ->
URL=io_lib:format("http://barrapunto.com/search.pl?threshold=-1&op=users&sort=1i&start=~.10B",[Pan]),
{ ok, {Status, Headers, Body }} = http:request(URL),
{match, Matches}=regexp:matches(Body,"barrapunto.com/~.*/journal"),
Lst_new = [string:substr(Body,Start+16 ,Length-16-8 ) || {Start,Length} <- Matches],
case Lst_new of
[] -> get_users_done;
%_ -> spawn(soc_graph,get_friends,[{Pid,Lst_new}]),
_ -> get_friends({Pid,Lst_new}),
get_users(Step+Pan,{Pid,Step})
end.

%get_friends gets user id and get friend list
%Pid is unused (refactoring?)
get_friends({Pid,[H|T]}) ->
URL=io_lib:format("http://barrapunto.com/~~~s/friends",[H]),
io:format("~s~n",[H]),
{ ok, {Status, Headers, Body }} = http:request(URL),
Reg_exp="barrapunto.com/~.*/friends",
{match, Matches}=regexp:matches(Body,"barrapunto.com/~.*/friends"),
Frnd_new = [string:substr(Body,Start+16 ,Length-16-8 ) || {Start,Length} <- Matches],
New_user=replace_forb_chars(H),
Frnd_flt=lists:filter(noself(New_user),Frnd_new),
to_file([{H,Frnd_flt}]),
get_friends({Pid,T});
get_friends({Pid,[]}) -> ok_friends.

noself(H) ->
fun(S) ->
case regexp:match(S,H) of
{match,_,_} -> false;
nomatch -> true;
{error,_} -> true
end
end.

%replace_forb_char replaces special (regexp) characters in user name
replace_forb_chars(S) ->
replace_forb_chars(S,".$()*+").
replace_forb_chars(S,[RH|RT]) ->
Regexp="["++[RH]++"]",
{ok,Newstr,_}=regexp:gsub(S,Regexp,Regexp),
replace_forb_chars(Newstr,RT);
replace_forb_chars(S,[]) ->
S.



%to_file writes friends into DOT file
to_file(Frnd) ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("bp.file",[write]),
to_file(F,Frnd).
to_file(F,[{User,Frnds}|T]) ->
%TODO: Format of map/frineds
Out_Frnd= fun(Frnd)-> io:format(F,"\"~s\" -> \"~s\"~n",[User,Frnd]) end,
lists:map(Out_Frnd,Frnds),
to_file(F,T);
to_file(F,[]) ->
file:close(F),
ok_to_file.

%init_file initializes the DOT file
init_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[write]),
io:format(F,"digraph mydot {~nnode [color=red, shape=ellipse];~n",[]),
file:close(F).

%end_file inserts the coda in the DOT file
end_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[append]),
io:format(F,"[weight=1, color=black];~n}~n",[]),
file:close(F).


La modificación para menéame:




-module(soc_graph).
-export([do_it/0]).
-export([get_friends/1]).
-export([get_users/1]).

do_it() ->
init_file(),
get_users({self(),1}),
end_file().

%get_users gets user list
get_users({Pid,Step}) -> get_users(1,{Pid,Step}).
get_users(Pan,{Pid,Step}) ->
URL=io_lib:format("http://meneame.net/topusers.php?sortby=0&page=~.10B",[Pan]),
{ ok, {Status, Headers, Body }} = http:request(URL),
{match, Matches}=regexp:matches(Body,"/user/[^\"]*"),
Lst_new = [string:substr(Body,Start+6 ,Length-6) || {Start,Length} <- Matches],
case Lst_new of
[] -> get_users_done;
%_ -> spawn(soc_graph,get_friends,[{Pid,Lst_new}]),
_ -> get_friends({Pid,Lst_new}),
timer:sleep(1000),
get_users(Step+Pan,{Pid,Step})
end.


%get_friends gets user id and get friend list
%Pid is unused (refactoring?)
get_friends({Pid,[H|T]}) ->
URL=io_lib:format("http://meneame.net/user/~s/friends",[H]),
io:format("~s~n",[H]),
Reg_exp="friends_of=[^\"]*",
{ ok, {Status, Headers, Body }} = http:request(URL),
{match, Start, Length}=regexp:match(Body,Reg_exp),
User_Id = string:substr(Body,Start+11 ,Length-11 ),
Frnd_new=get_friends_page(1,User_Id,[]),
New_user=replace_forb_chars(H),
Frnd_flt=lists:filter(noself(New_user),Frnd_new),
to_file([{H,Frnd_flt}]),
get_friends({Pid,T});
get_friends({Pid,[]}) -> ok_friends.


%get_friends_page gets friend list
%Pid is unused (refactoring?)
get_friends_page(Page,User_Id,Frnd) ->
Reg_exp2="/user/[^\"]*",
URL2=io_lib:format("http://meneame.net/backend/get_friends_bars.php?id=~s&p=~.10B&type=from",[User_Id,Page]),
{ ok, {Status2, Headers2, Body2 }} = http:request(URL2),
{match, Matches}=regexp:matches(Body2,Reg_exp2),
Frnd_new = [string:substr(Body2,Start2+6 ,Length2-6) || {Start2,Length2} <- Matches],
case Frnd_new of
[] -> Frnd;
_ -> get_friends_page(Page + 1,User_Id,lists:append(Frnd,Frnd_new))
end.

noself(H) ->
fun(S) ->
case regexp:match(S,H) of
{match,_,_} -> false;
nomatch -> true;
{error,_} -> true
end
end.


%replace_forb_char replaces special (regexp) characters in user name
replace_forb_chars(S) ->
replace_forb_chars(S,".$()*+").
replace_forb_chars(S,[RH|RT]) ->
Regexp="["++[RH]++"]",
{ok,Newstr,_}=regexp:gsub(S,Regexp,Regexp),
replace_forb_chars(Newstr,RT);
replace_forb_chars(S,[]) ->
S.

%to_file writes friends into DOT file
to_file(Frnd) ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[append]),
to_file(F,Frnd).
to_file(F,[{User,Frnds}|T]) ->
%TODO: Format of map/frineds
Out_Frnd= fun(Frnd)-> io:format(F,"\"~s\" -> \"~s\"~n",[User,Frnd]) end,
lists:map(Out_Frnd,Frnds),
to_file(F,T);
to_file(F,[]) ->
file:close(F),
ok_to_file.

%init_file initializes the DOT file
init_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[write]),
io:format(F,"digraph mydot {~nnode [color=red, shape=ellipse];~n",[]),
file:close(F).

%end_file inserts the coda in the DOT file
end_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[append]),
io:format(F,"[weight=1, color=black];~n}~n",[]),
file:close(F).


Referencias sobre Erlang

jueves, mayo 03, 2007

¿Postel o Dracón?

La primera vez que leí sobre la ley de Postel: "Sé conservador con lo que envias, liberal con lo que recibes"(*) me pareció tan filosóficamente interesante que intenté escribir una entrada al respecto, pero no supe, porque no tengo el gen gurú necesario para ello. Por eso, no está mal recurrir a los gurús de verdad, que sean ellos los que digan parte de lo que le ronda a uno por la cabeza. El caso es que en una semana dos blogstars de esto de la programación y la tecnología han comentado algo relacionado, así que les cedo la palabra, claro (cada una de las entradas da mucho más de si, pero claro, para eso está enlazadas, para que se lean ;)):

(*)Otras veces nombrado como "Sé conservador con lo que haces, liberal con lo que aceptas de otros". El enunciado es susceptible de ser políticamente interpretable más aún en esta segunda encarnación del principio. En este caso yo creo que es más bien interpretable desde el punto de vista de la ética. Como referencia se puede leer lo que dice Tim Berners-Lee acerca de esto y de una frase (que fué durante un tiempo firma mía) acerca del funcionamiento descentralizado "We have no kings or presidents. We believe in rough consensus and running code". Eso si, con grandes influencias de Unitarismo universalista, una religión más o menos buenrollista, si es que eso es posible...


"¿Postel o Dracón?" en barrapunto

lunes, abril 30, 2007

Entrevista sobre YARV

Vía la sección de reddit de programación (que a pesar de su sistema de filtrado y puntuación, también tiene el mal del exceso de información... ) he encontrado una serie de entrevistas sobre la nueva máquina virtual que ejecutará Ruby: YARV. Responden las dos personas más involucradas en ello, Matz (recordemos, el creador del lenguaje) y a Koichi Sasada, el desarrollador principal.

En la segunda parte de la entrevista se habla de las distintas implementaciones de los entornos de ejecución de Ruby. Por resumir, Koichi dice: "Necesitamos especificaciones, buenos test y buenos benchmarks". Por las bitácoras de barrapunto se ha hablado de ello, porque Robert h Quinn está trabajando en los test, según comentaba en GSoC 2007 : De que va mi proyecto

Sobre todo me ha gustado la tercera parte, sobre el pasado el presente y el futuro de los threads en Ruby.En esta parte se argumentan las razones por las que se abandonó la implementación de threads en espacio de usuario por el uso de los threads nativos del sistema, además de explicar como eso afecta el soporte de continuaciones.
(Hablamos de estas cosas hace unos meses en Noticias sobre Ruby 2.0 (que al parecer no son sobre 2.0 estrictamente...)

Actualización: Como me comenta Robert h Quinn, en On Ruby tienen una serie de entrevistas a los desarrolladores de distintas implementaciones de entornos de ejecución de Ruby. Más para leer...


"Entrevista sobre YARV" en barrapunto