Descargar

Scripting mIRC Optimización

Enviado por anih


    1. Rapidez o estabilidad
    2. ¿Cómo optimizar?
    3. Alto nivel – bajo nivel
    4. Los objetos de la optimización

    Este artículo describe los puntos más importantes para considerar la optimización en la escritura de código para mIRC. Muchas discusiones se han llevado a cabo a este respecto, y muchos autores consideran la optimización una razón importante para la programación, necesaria pero que no se suele usar. Intentaré realizar la descripción de un uso de la eficiencia no sólo desde el punto de vista de la ejecución, sino de la optimización de código, así como de la reutilización y actualización. También trataré de ir descubriendo técnicas para tratar de hacer el resultado final más intuitivo y eficiente, descubriendo cómo puedes realmente optimizar tu código. Aunque existen muchos y muy buenos artículos sobre depuración de código para mIRC Scripting, no me he basado en ninguno de ellos. Quiero decir que éste no es un artículo realizado a partir de otros artículos de mIRC, sino enfocado a un acercamiento sobre una programación más seria del lenguaje. El nivel de este artículo es para programadores ya avanzados.

    Rapidez o estabilidad La mayoría de las personas scripters suelen confundir rapidez con optimización. Así, cuando intentan hacer valer sus argumentos, explican, mediante código, que su realización es más rápida. Como se sabe ya desde hace mucho tiempo, la rapidez muchas veces está reñida con la estabilidad en cuanto a la programación se refiere. Yo puedo elegir realizar un bucle mucho más rápido que la realización de la llamada a un alias.

    Sin embargo, cuando estamos operando con características reales, no suele ser la mejor opción. Por ejemplo, imaginémonos que debemos realizar un bucle que tome como parámetro de entrada los usuarios de un canal y nos dé como salida una sencilla cadena con todos ellos. Mediante un bucle while se podría obtener inmediatamente el resultado, pero ¿qué pasaría si el parámetro de entrada se retrasara unos segundos? Pues nos devolvería una cadena partida, errónea o, incluso, no devolvería nada. Para solucionar este problema se suele utilizar un retraso virtual, que puede ser un contador o un timer. De esta forma, aun evitando la posible nula salida, tendremos como resultado que, lo que al principio pensabamos realizar eficientemente y rápido, nos encontramos ahora con un código dependiente, enlentecido e inestable.

    Si añadimos un timer para esperar a tener todos los valores de entrada, un timer que debería ser preconfigurado por nosotros a un tiempo no escalable y prefijado, la rapidez, que era lo que se perseguía, quedaría gravemente mermada. Así, lo que en un princpio se podría rechazar por lentitud, como sería la llamada a un alias que se activara en un raw dependiente de la notificación, por parte del servidor, de la finalización de envío de los datos que requiramos, resulta ser ahora la manera más precisa y óptima de codificar. Éste es un claro y sencillo ejemplo para plasmar que un código rápido no es siempre la mejor opción, y que la rapidez no lleva consigo, obligatoriamente, la optimización.

    ¿Cómo optimizar? Es posible dividir las líneas de código compartidas en partes individuales, realizar llamadas dependiendo de los eventos realizados por el usuario y prever los posibles conflictos o terminaciones erróneas de las llamadas realizadas. mIRC nos ofrece amplios recursos para ello, que no es materia de este artículo explicar, ya que lo alargaríamos demasiado y no es nuestro objetivo dar clases de programación. Se supone que quien scriptea seriamente esos recursos ya sabe usarlos. Con la optimización se adelanta y se aclaran una serie de errores que pueden darse habitualmente durante la ejecución de un código, como son: -la optimización es una forma eficaz para la detección de bugs -algunas técnicas de optimización harán que tu código sea más portable -tú obtienes más control sobre tu código -la optimización hará que tu código sea duro, consistente, estable y firme

    Existen diversas técnicas, todas ellas legítimas y que entran más en el terreno de los gustos personales y de la manera de cada uno que del propio resultado final.

    Mientras el punto de conclusión sea parecido, no debe importar tanto qué camino o caminos tomamos para ello. Sin embargo, y sin que sirva como modelo preferencial, para una visión didáctica del tema pasaré a relatar por encima el propio estilo que sigo personalmente. Primeramente, no puedes dividir tu código y hacerlo más óptimo mientras no tengas claro qué funciones persisten en él y cuál es su cometido. No puedes tratar de la misma forma todo ya que tú no tienes potestad sobre el motor de ejecución (hay que recordar que estás programando para un programa, valga la redundancia, no el programa en sí. De ahí que se llame scripting). Yo divido las partes del mIRC y todo lo que influye en éste en varios campos*1: primeramente, el mIRC no como programa, sino como generador y soporte, lo que se denomina mIRC engineered scripting (motor de scripting del mIRC). A continuación, y sobre ello, se ensambla, lo más perfectamente posible, el código principal. Es el código con el cual, sin él, el script no sería script, no funcionaría o, en caso de alterarse, podría funcionar erróneamente*2. Es lo que denomino "kernel" del script. En las primeras actualizaciones el kernel era necesario para actualizar el script. Después ya no era imprescindible ya que se le puede añadir soporte para actualización. El motivo de haber retartado esa actualización era la ligereza del código final, y encontrar un punto medio llevó su tiempo.

    Hay que tener en cuenta que el kernel es capaz de trabajar, teóricamente, con cualquier addon medianamente bien programado. Tras el kernel se encuentran unos archivos de uso de cara al programador, es lo que se denomina "modules support & interprety"*3. En ellos englobaríamos los ini, módulos, etc. Encima de todos ellos esta el integrity check, que es la defininición para conjuntar tanto los errores que pueda captura el mIRC como programa de ejecución, o el propio script. Es conveniente tener bien claro este concepto. Como parte final y de nivel más alto se encuentra lo que denomino "scans and external reads", son archivos de usuario y engloba todo lo que el usuario puede añadir y hacer. Como se puede ver, está en el nivel más alejado ya que no lo considero imprescindible, pues su uso cae en manos del propietario del script. Por poner un ejemplo extremista: yo no puedo prever que él introduzca código de un troyano. Repito que ése es un modelo que me sirve a mí, y está expuesto como materia didáctica. Soy consciente de que muchos programadores están desarrollando sus propios modelos (otros los han desarrollado ya) que son tan válidos como éste, o más.

    Alto nivel – bajo nivel Hoy ya se tiene mucho más claro la frontera que dividen estos dos conceptos, sin embargo, hace apenas unos años no se entendía y apenas se hacía uso de ellos. Solamente los scripters más vanguardistas fueron capaces de usarlo. En palabras llanas, un programador-scripter que empieza en el mundillo de la programación realizando su script, o que empieza en el mundillo del scripting haciendo lo propio, sin más aspavientos ni complicaciones que generar una suerte de archivos capaces de reaccionar ante determinados eventos realizados por el usuario o el IRC o/y cualquier otro programa (objetos com dlls, etc.), podría denominarse como un scripter de alto nivel. Su código no persigue más allá que cumplir una serie de objetivos puntuales. Cuando lo que se persigue va más allá, es decir: dotar a tu script de la capacidad de iteracción, reacción y previsión de conflictos, de dialogar abiertamente con cualquier ambiente en el que se halle (tomando como límites, por supuesto, la propia limitación del scripting y del ambiente en el que se mueve), así como capacitación para incluir addons nativos, estamos hablando de programación en scripting a bajo nivel. No es lo mismo, como algunos erróneamente consideran, entre programar para pics wins o para dlls. Eso entra más dentro de los gustos personales que de la forma de englobar la optimización, aunque tanto uno como otro pueda ser más o menos óptimo.

    Los objetos de la optimización Por término medio, nadie debería: -Declarar un halt sin previa reconsideración de su código. Los halt deberían reservarse para eventos planos, tales como capturas de raw o reacciones verdaderamente irremediables. -Declarar un bucle sin haber finalizado e iniciado variables predefinidas. ¿Cuántas veces nos hemos encontrado con scripts que aprovechan variables? Creo que muchos equivocan el concepto de reutilización de código con el de reutilización de variable.

    Gran pecado, puesto que estos peligros solamente suelen presentarse cuando ya es demasiado tarde. En el otro aspecto, la finalización, corre a nuestro favor que el motor de mIRC posee un buen "recolector" (aunque no sea propiamente eso) que concluye la variable local. Sin embargo, deberíamos tener siempre en cuenta en qué estado puede concluir esa variable, no es siempre la manera más óptima la que se nos ofrece por defecto. -Declarar variables como locos. Antiguamente eso se utilizaba mucho. Afortunadamente, hoy cada vez se lleva menos. La diferencia de una declaración de variables limpia no es tanta la eficiencia del propio script (muchos suelen argumentar que es lo mismo, puesto que la diferencia objetivamente entre 100 y 200 variables no es mucha).

    En la práctica, una manera tan fea y errónea de programar puede llevar al usuario a que trabaje con varias variables a la vez, con la consiguiente confusión y el peligro de la integridad de nuestro código. Las variables deben ser únicas, las genéricas escasas, reconocibles y, cuanto sea posible, locales. -Realizar las llamadas a alias. Para reutilizar código hay que ser extraordinariamente ordenado. Tú no puedes realizar las llamadas a unos alias de reaprovechamiento si los tienes desperdigados por todos los códigos remotes. Los buenos scripts catalogan sus genéricos en sus archivos alias y solamente ponen los locales, o los que van a usar en el propio archivo remotes. -Reutilizar código no es reutilizar salidas. No es buen concepto para la optimización el que aproveches un return para derivarlo a otro alias. Si un return debe ser procesado, se entiende que debe ser procesado dentro del propio alias. Partir alias para aprovecharlos puede llevarte al otro extremo de lo que quieres lograr, es decir: a la ineficiencia.

    Conclusión Para finalizar, resumiré, en varios puntos, partes que se deben tener en cuenta, algunas ya expuestas y otras que dejo a la consideración de tu propia valoración: -Los recursos de dlls enlentecen. Usa scripting puro siempre que puedas, aunque también recurras a dll. No lo dejes todo para las librerías. -Minimiza grafismos si persigues rapidez. -Precalcula límites de hash y de lecturas de buffers. -Previsiona salidas de bucles. -Intenta valorar roturas de código. -Usa elementos propios del lenguaje -Reutiliza los elementos más frecuentes -Elimina nombres comunes o denominaciones de dialogs y ventanas populares -Usa contadores pequeños -Usa algorítmica de testeo -Usa llaves, usa elses para tratar idéntica entrada, en definitiva: usa una buena metodología de programación -Preserva la compatibilidad de tu script con diferentes versiones La optimización no es sustituto de la experiencia. Un programador inexperto puede cometer más errores tratando de optimizar que codificando a la ligera*4. Pero eso no debe llevar a nadie a la desesperación o el abandono de buenas prácticas, la optimización debe ir creciendo conforme va creciendo el aprendizaje. No es necesario que se sigan estrictas reglas de diversificación o modelaje de un script, pero sí es imprescindible tener bien claro sobre qué elementos y lenguaje se trabaja. Esto es esencial. Tal vez con esta versión de tu script no logres que sea lo más homogénea y robusta que deseas, pero seguro que la posterior será mejor. Desde ese punto de vista es desde el cual debes programar.

    *1La división es meramente subjectiva, y se realiza solamente como una idea conceptual para el posterior tratamiento. *2Los archivos del corazón del script no están separados físicamente *3El modules support & interprety no son archivos kernel propiedad del programador, sino que son archivos destinados a cualquier programador. Lo que técnicamente se denominaría como archivos no propietario. *4Se entiende que la recursividad virtual añadida al scripting es materia que deben conocer expertos programadores, un chaval que empieza a scriptear puede encontrarse al final de todo su empeño con un script destructivo e inoperante.

    ©Arphean 2004

    Para cualquier contacto:

    Gracias a Nifelheim por repasos y correcciones Se permite copia y distribución siempre y cuando se cite la fuente de procedencia y su autor.

     Datos del autor y datos de interés: -Arphean (Manuel González) es informático y programador desde 1996. En torno al año 2000 comenzó a programar en scripting distribuyendo gratuitamente el h@ckScripT a todos los usuarios del mIRC que lo desearan. Actualmente dispone de su web en: www.arphean.mirrorz.com -Los usuarios del h@ckScripT disponen también de una web específica, construida por los fans y seguidores del script, que está alojada en www.hackup.cjb.net -Arphean posee varios trabajos publicados en torno al mIRC Scripting, así como a determinadas áreas de la informática. Asimismo, es colaborador del Departamento de Informática y Sociedad en la Escuela de Ingeniería Informática de la Universidad Abierta bajo licencia GNU. -El presente archivo es un trabajo 100% original, fruto de la experiencia propia y de la interrelación con diferentes usuarios, programadores y testers de scripts. -El título y la categoría se englobarían en Computación/Internet