Ver Mensaje Individual
  #8 (permalink)  
Antiguo 18/08/2003, 15:30
leonardop
 
Fecha de Ingreso: julio-2003
Mensajes: 165
Antigüedad: 20 años, 9 meses
Puntos: 1
Hola nuevamente Bluesman... a propósito ¿ese nick tiene algo que ver con el hermoso género musical?

Y bueno, te agradezco los comentarios que haces sobre el manual. Tan solo queria hacerte saber que en caso de que encontrases errores en la traducción al castellano del manual, o tuvieras cualquier comentario al respecto, me gustaría que me lo hicieras saber. Y ya que hablo de esto, aprovecharé para invitar a todas aquellas personas que deseen colaborar con una buena causa, que le echen un vistazo al grupo PHPDoc-es, en donde se trabaja por generar y administrar la versión en Castellano del manual oficial de PHP. La colaboración de todos es muy bienvenida. Quizás ya se ha hablado sobre este grupo en este foro, pero por si acaso... :)

Respecto a MySQL, pues me alegra que estés dispuesto a aprender, mas allá de los inconvenientes con que te puedes topar al principio. La pregunta que te haría inicialmente es, ¿en qué punto empiezas a confundirte un poco? ¿ya estás familiarizado con las bases de datos relacionales en general y el lenguaje SQL? De ser así, y si se trata de un asunto de MySQL ¿tu problema es específico a la instalación, configuración o uso de MySQL?

Quizás me anime a escribir, un día de estos, un pequeño documento de introducción a las bases de datos relacionales, entrando quizás en algunos detalles particulares a MySQL y PostgreSQL, si llegara a motivarme la necesidad. :)


Finalmente, quería comentar un poco sobre un comentario de nuestro amigo Manoloweb.

Cita:
Solo debes tomar en cuenta que este archivo demanda recursos como cualquiera, así que si en una pagina solo vas a usar una funcion, y tu include tiene 50 funciones, vas a estar desperdiciando recursos y haciendo tu sitio mas lento.
Desconozco si la verdadera intención de Manoloweb era recomendar la curiosa práctica de mantener el menor número posible de funciones y código por archivo, basándose exclusivamente en razones de rendimiento.

Digo `curiosa', porque ciertamente me intriga mucho esta percepción, que por lo demás, he notado en muchos programadores. Hay quienes eventualmente piensan que es mejor tener la menor cantidad de código posible dentro de cada archivo fuente, ya que esto repercutiría de alguna forma significativa en el rendimiento de la aplicación, especialmente en su tiempo de ejecución.

Yo considero esto un mito que produce un efecto más negativo que positivo a la labor de un programador. Ciertamente, y creo que nadie defendería lo contrario, no es lo mismo contar con un archivo de 10 líneas que con uno de 10,000. Pero, si consideramos las variables de las que depende el tiempo de ejecución de un programa con un poco de detalle, veremos que el hecho de tener un archivo con una cantidad enorme de funciones que no serán ejecutadas, no tienen impacto significativo alguno en la ejecución de las aplicaciones.


En términos generales, los lenguajes interpretados como PHP realizan más o menos los siguientes pasos cuando se ejecuta un script:

* (el paso obvio) Se abre el archivo fuente para lectura.

* En este punto, dependiendo del lenguaje, pueden ejecutarse varias acciones. Por ejemplo, pasar por un paso de preprocesamiento (muy al estilo C). En PHP, quizás lo más cercano a las labores de preprocesamiento son las sentencias tipo include() o require(), aunque estas en realidad son protagonistas en tiempo de ejecución. Curiosamente, construcciones del lenguaje como include(), require(), o la función define() no trabajan en tiempo de compilación por decisión de diseño.

* Después del preprocesamiento se pasa a la compilación. Inicialmente, suele hacerse un análisis lexical, lo cual implica un procesamiento del contenido completo del archivo, y en donde se verifican correspondencias entre los símbolos del código y los lexemas del lenguaje.

* Nuevamente dependiendo del lenguaje, usualmente se pasa a la generación de un árbol sintáctico. En el proceso de construcción del árbol se pueden verificar algunos aspectos de la gramática del código original.

* Una vez se cuenta con el árbol sintáctico, puede hacerse uso de otro paso de análisis semántico, en donde se verifican otros aspectos de la integridad del código.

* En fin, ya después de los análisis sintácticos, los intérpretes pueden pasar a la generación de código intermedio para su ejecución. Opcionalmente, puede haberse pasado por una o más fases de optimización.

* El resultado final de todo el proceso es el lenguaje de máquina que finalmente es pasado a la unidad de procesamiento de la máquina. Aquí comienza efectivamente la ejecución del programa, y lo que suceda de aquí en adelante recae enteramente en el diseño del programa original.


Es comprensible la adopción de apreciaciones que sugieren que es buena idea ser frugal en cuanto a líneas de código por archivo se refiere. Pero lo que se está desconociendo en tales situaciones es la tremenda sofisticación a la que llegan los intérpretes modernos para lograr que las fases fundamentales de análisis del código sean eficaces.

Por supuesto que para un programador, la tarea de escribir una cantidad considerable de código (digamos, unas 100,000 líneas de código relativamente interesante) ¡es muy apreciable! Pero para el intérprete todas estas sentencias no representan más que elementos lexicales que corresponden a un número finito de ciclos de procesamiento elementales en las etapas de generación de código intermedio.

Intuitivamente, podría decirse que la complejidad computacional de las fases de generación de código intermedio del intérprete sería algo como O(n), donde `n' corresponde al número de expresiones, operadores, y demás símbolos dentro del código fuente original. Claro está que en la realidad, la expresión de esta complejidad sería algo más cercano a: O(n) + k, en donde k es una constante que representa el tiempo que toma el intérprete realizando tareas que son independientes al código que llega como entrada.

Ahora bien, sin entrar a hablar de cifras exactas, que por lo demás no considero necesarias en este punto, creo que todos podríamos coincidir en que el tiempo de procesamiento de un símbolo dado, usando el tipo de equipos (procesadores) que existen hoy en día, es algo muy, muy rápido. Probablemente estoy diciendo una barbaridad, y muy seguramente, y deliberadamente, me referiré a un número exageradamente grande. Digamos que un símbolo dado, en las etapas de generación de código intermedio de un intérprete, se procesa en aproximadamente 1e-6 segundos. Digamos que en nuestro ejemplo anterior, en donde hablábamos de 100,000 líneas de código, cada línea tenía en promedio unos 5 símbolos (cosa por lo demás difícil de creer si se consideran los espacios en blanco, los comentarios, las expresiones como cadenas de caracteres de considerable tamaño, etc.). Estamos pensando entonces de un programa con unos 500,000 símbolos. Este programa con nuestro intérprete, y en nuestro procesador imaginario tomaría: 500,000 * 1e-6 segundos, siendo procesado en las etapas previas a la ejecución real de la aplicación. Es decir, unos 0.5 segundos.


Como sé que es más fácil ver las cosas con valores reales, y no con cifras aleatorias que se le ocurren a cualquier aparecido (es decir, éste servidor :), preparé el siguiente ejercicio que ejecuté en mi máquina personal. Mi máquina no es nada sofisticada, cuenta con un procesador de ~750Mhz (pentium3) y unos 384MB de memoria RAM.

Estos son los resultados de reunir una cantidad grande de código --unas 2400 líneas de código tomado del proyecto Smarty de PHP (inicialmente quise hacerlo con el repositorio completo de clases de PEAR, pero abandoné la idea después de observar la enorme cantidad de errores que hay dentro del código de este repositorio, y que no permitían ejecutar el script de prueba). El código se reúne en un único archivo, y luego es ejecutado. Internamente, en el archivo sólo se hace un llamado a una función, de las muchas que hacen parte del archivo.

Para poner las resultados en perspectiva, al final realicé el mismo experimento con un archivo que únicamente incluía una función, la cual es llamada una sola vez. Comparando los tiempos de ejecución finales puede verse que no hay alguna diferencia significativa entre los dos casos.

(continúa)