Curso AppleScript: Optimizar Scripts, por Julifos

La regla básica del cualquier programador en cualquier lenguage es “una aplicación nunca está terminada por completo”. Por tanto, podemos decir que la aplicación es “perfecta” cuando es “la más perfecta que existe de entre las que hacen las mismas cosas”.

Entonces, una aplicación es perfecta únicamente cuando se cumplen las siguientes condiciones:

– El programa siempre se ejecuta hasta el final (hasta la última línea de código) y el usuario lo puede constatar.

– La ejecución del programa es la más rápida posible.

– El programa cuenta sólo con los recursos indispensables.

– Los resultados de ejecutar el programa son óptimos.

– El programa acompaña una buena documentación.

El programa siempre se ejecuta hasta el final

El programador debe prever todas las posibilidades (que se ajusten a sus intereses) y ser capaz de atenerse a ellas.

Más concretamente, se trata de probar la viabilidad del asunto. Por ejemplo, si queremos desarrollar un script para “Internet Explorer 25”, que soporta un comando llamado “hazlotodo”, antes de utilizar dicho comando, deberíamos comprobar si la versión de “Internet Explorer” que tiene un hipotético usuario es la “25”. Y si no, notificárselo. Por ejemplo:

tell application “Finder”

 set InternetExplorer to (file of first process whose creator type = “MSIE”) as alias

 set IEVersion to short version of (info for InternetExplorer)

end tell

Con los modernos “packages”, tendríamos que sustituir la segunda línea por “set IEVersion to version of result”, y tendríamos la versión “larga” del paquete. O se podría buscar un camino alternativo, etc.

Aquí llamamos al Finder y obtenemos un alias de la primera aplicación activa cuyo creador es “MSIE” (el creador de Internet Explorer). Luego, con la segunda línea, obtenemos la versión del programa.

Ya podemos comprobar si el Explorer del hipotético usuario es o no la “25”.

Como hemos dicho que el programa se debe ejecutar hasta el final, en este ejemplo deberíamos utilizar un condicional para ver si podemos o no seguir con el proceso.

if “25” is not in contents of IEVersion then

 display dialog “Esta aplicación es sólo para la versión 25 de Internet Explorer”

 return

end if

Nuestro programa ha funcionado perfectamente. Si la versión del usuario es la “25”, seguirá adelante. Si no, le informará de que se ha descargado algo inútil. Por supuesto, podemos convencerle de que lo que se ha descargado no es inútil, sino que tiene una versión del Explorer que es una mierda, y que se debe descargar la “25” antes de nada. Por ejemplo, podemos hacerlo así:

display dialog “Oiga mire, no es que vd. sea un capullo. Es que la versión del Explorer que tiene es una mierda. ¿Por qué no se descarga la versión 25, que es mejor?” buttons {“No quiero”, “Está bien”} default button 2

if button returned of the result = “Está bien” then open location “http://descargar_la_25.com/”

return

Ya hemos conseguido dos cosas: que el usuario sepa que su versión 3 del Explorer es una mierda y que tiene que utilizar la buena, para que pueda utilizar nuestro programa sin problemas.

Chequear las condiciones de ejecución es una alternativa. La otra, y ante la posible imposibilidad de que esto sea imposible, dar una alternativa eficaz y resolutiva: los try “statement”.

Supongamos que nuestra aplicación utiliza comandos de la adición de script “Jon’s Commands”. Entonces, podemos hacer varias cosas: chequear si está instalada (en la carpeta de “Adiciones de script” de la “Carpeta del Sistema”, o en OS X en diversas localizaciones) y utilizar un condicional (if “no está”, bla, bla, bla), o directamente tratar de utilizarla:

try

 set sound volume to (sound volume)

on error

 display dialog “No tiene vd. instalados los Jon’s Commands, indispensables para mí”

 return

end try

display dialog “¡Podemos seguir adelante!”

“set sound volume” y “sound volume” son comandos propios de los “Jon’s Commands”. Por eso, si el usuario no los tiene instalados, dará un error. Y, ante el error, se ejecuta nuestro código avisando al usuario de que los necesita para ejecutarse.

Por si no ha quedado claro, y como excusa para poner más ejemplos, ahí va el siguiente: supongamos que nuestra aplicación va a hacer una lista de canciones para luego poder hacer algo con ellas (abrirlas con QuickTime, por ejemplo). Queremos guardar esta lista de canciones en un archivo de texto para poder utilizarlas después (o dentro de diez meses) y, por algún motivo, nos gusta que se guarde en el Escritorio y se llame “lista.txt”. Ahí va:

set las_canciones to “1. La cucaracha

2. Baby, I love you”

tell application “Finder”

 try

  (path to desktop as text) & “lista.txt” as alias

  set la_lista to (new file with prompt “Elija un nombre para la lista”)

 on error

  set la_lista to (make file at desktop with properties {name:”lista.txt”})

 end try

end tell

set Archivo_Abierto to open for access la_lista with write permission

set eof of la_lista to 0

write las_canciones to Archivo_Abierto

close access Archivo_Abierto

En este código, la línea 5 comprueba si existe un archivo en el Escritorio llamado “lista.txt”. Si no existe, lo crea. Si existe, crea uno nuevo para no desgraciar el antiguo. Y, finalmente, escribe los datos.

Nuevamente, el código ha llegado hasta el final.

Por último, vamos a suponer que estamos en la España de los años 40 y que estamos desarrollando un programa para Francisco Franco. Enfrentándose al problema de la neutralidad durante la Segunda Guerra Mundial, él sólo quiere programas para sistemas operativos españoles, así que nosotros debemos hacerle caso. Entre otras muchas otras cosas, para saber si el sistema operativo del usuario es o no español, podemos hacer lo siguiente:

try

(path to startup disk as text) & “Carpeta del Sistema:” as alias

on error

display dialog “Lo siento, pero soy neutral como Suiza”

return

end try

display dialog “Es vd. español y, por tanto, neutral en esta guerra.” & return & “Sigamos adelante.”

Aquí hemos comprobado si existe la carpeta “Carpeta del Sistema” dentro del disco de arranque. Si no existe (porque se llamará “System Folder” o algo por el estilo), podemos presuponer que el sistema operativo del usuario no es español y, por tanto, eso cabrearía a Franco si el programa funcionase. Así que, no levantemos ampollas. (un chiste para castellano-hablantes: “¿Hay ampollas?”, dijo. “Hello, mister Pollas”, respondió.)

La ejecución del programa es la más rápida posible

Pondré un ejemplo muy sencillo.

Necesitamos una adición de script que busque unas palabras en un texto y las reemplace por otras que nos interesan más. Hay muchas adiciones de script que llevan a cabo esta función. Debemos elegir la más rápida de todas:

set el_texto to “El mundo es muy profundo”

repeat 1000 times

 replace string “mundo” in the text el_texto with string “agujero”

end repeat

repeat 1000 times

 Acme replace “mundo” in el_texto with “agujero”

end repeat

El primero comando, “replace string”, es de las “Kamprath’s Text Utilities”, y tiene una velocidad media (en este ejemplo) de 0.0037 segundos. El segundo, “Acme replace”, es de “ACME Script Widgets”, y tiene una velocidad media de 0.0016 segundos. O sea, que es más del doble de rápido (y “Satimage” es más rápido todavía).

Deberíamos elegir en este caso “ACME Script Widgets”, aunque nos caiga muy bien Michael J. Kamprath.

La pregunta es: ¿quieres que te toque la lotería dentro de un año, o de dos? O, en su defecto: ¿quieres que te claven cuchillas sólo en un ojo o mejor en los dos?

Otro ejemplo más complicado: la “decodificación de URL”. Sabemos, o deberíamos saber, que en la codificación vulgarmente llamada “URL”, el carácter return de mac (ASCII 13), corresponde a “%0D”. Supongamos que estamos trabajando en una aplicación que recibe este tipo de texto codificado y queremos transladarlo al valor que nos interesa. Entonces tenemos varias posibilidades: utilizar una adición de script que lo haga (que existe, pero que no queremos utilizar), utilizar una rutina de conversión rápida y otra lenta.

No sabemos cuál es la rutina rápida y cuál la lenta.

Primero vamos a probar las dos, a ver qué pasa:

decode_rapido(“file:///HD/Desktop%20Folder/Carpeta%201/archivo.html”)

decode_lento(“file:///HD/Desktop%20Folder/Carpeta%201/archivo.html”)

property ascii_table : create_ASCII_table()

property hexa : “00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF”

— entre las parejas de caracteres, HAY QUE PONER 2 ESPACIOS, y no uno sólo!!!

to decode_rapido(t)

 set AppleScript’s text item delimiters to “%”

 set t to t’s text items

 set AppleScript’s text item delimiters to {“”}

 set final_string to {t’s item 1}

 repeat with i in (items 2 thru -1 of t)

  set to_decode to text from character 1 of i to character 2 of i

  try

  set the_rest to text from character 3 of i to character -1 of i

 on error

  set the_rest to “”

 end try

 set final_string’s end to (item ((((offset of (text from character 1 of i to character 2 of i) in hexa) – 1) / 4) + 1 as integer) of ascii_table) & the_rest

 end repeat

 return final_string as text

end decode_rapido

to create_ASCII_table()

 set ascii_table to {}

 repeat with i from 0 to 255

  set ascii_table’s end to ASCII character i

end repeat

return ascii_table as text

end create_ASCII_table

on decode_lento(theText)

 set flag_A to false

 set flag_B to false

 set temp_char to “”

 set the character_list to {}

 repeat with this_char in theText

  set this_char to the contents of this_char

  if this_char is “%” then

   set flag_A to true

  else if flag_A is true then

   set the temp_char to this_char

   set flag_A to false

   set flag_B to true

  else if flag_B is true then

  set the end of the character_list to ¬

  my decode_chars((“%” & temp_char & this_char) as string)

  set the temp_char to “”

  set flag_A to false

  set flag_B to false

 else

  set the end of the character_list to this_char

 end if

 end repeat

 return the character_list as string

end decode_lento

on decode_chars(these_chars)

 copy these_chars to {indentifying_char, multiplier_char, remainder_char}

 set the hex_list to “123456789ABCDEF”

 if the multiplier_char is in “ABCDEF” then

  set the multiplier_amt to the offset of the multiplier_char in the hex_list

 else

  set the multiplier_amt to the multiplier_char as integer

 end if

 if the remainder_char is in “ABCDEF” then

  set the remainder_amt to the offset of the remainder_char in the hex_list

 else

  set the remainder_amt to the remainder_char as integer

 end if

 set the ASCII_num to (multiplier_amt * 16) + remainder_amt

 return (ASCII character ASCII_num)

end decode_chars

En este caso, la primera rutina no es sólo más corta que la segunda, sino que además es el doble de rápida. Aunque las diferencias no sean astronómicas, sí que pueden llegar a serlo si la rutina se utiliza muchas veces o si se van sumando las veces que se utilizan, de una en una.

¿Y cómo sabemos qué método es más rápido?

Pues hay varias maneras.

Hay un par de aplicaciones que lo hacen. Una se llama “Script Timer” y otra “Time Script”, pero ambas hacen algo parecido (y una es “freeware” y otra “shareware”), pero vamos a explicar brevemente cuál es el proceso. Con un ejemplo, por supuesto.

coger el tiempo

> ejecutar rutina 1

coger el tiempo

> ejecutar rutina 2

coger el tiempo y comparar las dos rutinas

Aunque se puede hacer de muchas maneras, vamos a utilizar, para coger el tiempo, el comando “the ticks”, de los “Jon’s Commands” (los “ticks” se miden desde que el ordenador se arrancó, y 60 “ticks” son 1 segundo). Añadamos los handler (decode_rapido y decode_lento) a estas líneas de código:

set i1 to the ticks

repeat 100 times

 decode_rapido(“file:///HD/Desktop%20Folder/Carpeta%201/archivo.html”)

end repeat

set i2 to the ticks

repeat 100 times

 decode_lento(“file:///HD/Desktop%20Folder/Carpeta%201/archivo.html”)

end repeat

set i3 to the ticks

set st1 to ((i2 – i1) / 60) / 100

set st2 to ((i3 – i2) / 60) / 100

display dialog “El método rápido tarda ” & st1 & ” segundos, y el segundo, ” & st2 & ” segundos.”

* Requiere la adición de script “Jon’s Commands”. Comprobar si está instalada

Repetimos 100 veces cada rutina para obtener un resultado que se aproxime a la realidad (0.0002 segundos no nos sirven para compararlos a 0.000195). Lo que obtenemos al dividir por 100 es el tiempo que transcurrió aproximadamente entre cada “repeat”.

Las condiciones óptimas para probar la velocidad son desde una aplicación (el script guardado como applet o droplet), con el ordenador recién arrancado y sin ninguna aplicación abierta.

Como ya hemos dicho, lo habitual es que la velocidad no sea demasiado apreciable. Pero si empezamos a sumar las veces que uno utiliza la subrutina, entonces sí que sale mucho tiempo (del cual podemos disponer, por ejemplo, para masturbarnos o comer aceitunas).

Estas velocidades pueden variar bastante según el texto a decodificar, pero el primer método suele ser bastante más rápido. He de decir que es de mi invención y (muy probablemente) no es el único ni el más rápido. El segundo es un ejemplo de subrutina de los “AppleScript Guide Modules” de Apple.

Pues eso, que cuanto más rápido, mejor.

El programa cuenta sólo con los recursos indispensables

Esto es muy relativo, pero me refiero a que no hagamos cargar al usuario con cosas que no necesita para nada. Por ejemplo, no me parece lógico que si nuestro programa tiene un tamaño de 10Kb, le metamos 2Mb de documentación.

A lo mejor es el super-programa y, efectivamente, requiere 2Mb de documentación, pero no es lo habitual.

Además de eso, nunca tenemos que dar por supuesto que el usuario que utiliza nuestro programa sabe qué es lo que hace, porque lo habitual es que no tenga ni idea.

Por tanto, y tomando el ejemplo del anterior capítulo, sería preferible utilizar las rutinas anteriores (para decodificar texto) a utilizar un comando “osax” que requiera la instalación adicional de la “script addition” en cuestión (por ejemplo, “Tanaka’s osax” o “EncodeDecodeURL”).

No nos engañemos. Nuestra aplicación nunca será tan complicada como un “PhotoShop” o un sistema operativo, así que no nos compliquemos con requerimientos de sistema, multitud de adiciones de script y otros recursos, y utilicemos sólo lo indispensable.

Tenemos que saber elegir los recursos, para utilizar los menos posibles. Por ejemplo, la adición de script “Akua Sweets” tiene una versatilidad impresionante, pero su descarga supone aproximadamente 1Mb (unos 5 minutos para un módem de 28.8Kb).

Evidentemente, para nosotros mismos podemos utilizar todo lo que nos dé la gana. Pero cuando estamos desarrollando aplicaciones para terceras personas o usuarios desconocidos, tenemos que facilitar las cosas cuanto más mejor.

En cuanto a la interface del programa (los elementos gráficos de cara al usuario), no tengo nada que objetar. Si es necesaria una presentación espectacular, hágase. Si nuestro programa merece un icono distinto de un sencillo “applet”, vamos a ponérselo.

Pero que esto nunca perjudique al rendimiento del programa.

Está claro que la interface siempre es un acierto a la hora de comercializar el programa. No tenemos más que ver a MicroSoft, con su famosísimo Ayudante de Office y sus programitas llenos de colores, sonidos y chorraditas. Pero a nivel de programación lo que más cuenta es la estabilidad y la eficiencia del programa, y suele coincidir que los programas más espectaculares son los más lentos, mierderos y poco efectivos.

Los resultados de ejecutar el programa son óptimos

Una vez ejecutado el programa, tenemos que haber resuelto por entero el problema del usuario, y que él lo sepa. Ese es el objetivo más importante (¿y si no, para qué programamos nada?).

Me da igual que el programa sea sólo para procesadores de 68K o sólo para usuarios de “Eudora”. El resultado debe ser satisfactorio para cualquier persona que haga doble click sobre nuestra aplicación, ya sea para decirle “su trabajo está hecho”, como para decirle “¿y vd. para qué me necesita, si no tiene instalado el Eudora?”.

El usuario tiene que poder decir una de las dos cosas siguientes después de ejecutar nuestro programa:

1. Qué maravilla de programa, qué bien hace las cosas.

2. Qué idiota soy, para qué querré este programa tan bueno y efectivo que no me hace ninguna falta.

Y nunca:

a) ¿Para qué servirá esto?

b) ¿Qué habrá hecho esto?

c) ¿Tendré un virus?

La mayoría de aplicaciones escritas en AppleScript sólo hacen una cosa (vaciar la papelera, imprimir documentos…). Y por sencilla que sea ésta, deben hacerla bien. Y, a ser posible, mejor que ninguna otra, más rápido, con más efectividad.

Un tema importante es el de la documentación del programa.

El programa acompaña una buena documentación

Una vez resueltos los problemas del “usuario estándar”, que sólo sabe hacer doble click sobre nuestra aplicación, tenemos que intentar resolver también los del “usuario no estándar”. O sea, del que está interesado en lo que hemos hecho.

Está uno harto de encontrarse con programas de pago que son una mierda o tan vulgares que se puede reproducir su comportamiento en cinco minutos, entre bostezo y bostezo.

Pero como cada uno es libre de comprar y vender lo que quiera, como consejos gratuitos para ambos tipos de programa, apunto los siguientes:

– Que el usuario sepa qué hace el programa y cómo tiene que hacerlo funcionar.

– Si es necesaria alguna instalación especial, simplificar las cosas lo máximo posible (acompañar un instalador o una explicación detallada acerca de ello).

– Que estén claros los requisitos necesarios para que funcione la aplicación (de sistema operativo, adiciones de script… lo que sea).

– Que el usuario sepa a quién acudir en caso de duda. Y, en caso de que no haya a quién acudir, que también quede claro. Si nuestra aplicación está dirigida al gran público, es importante que acompañe una licencia, que especifique si la aplicación es o no gratuita y si el usuario tiene derecho o no a algún tipo de soporte técnico. Esto ahorra muchos problemas a ambas partes (programador y usuario).

– Si la aplicación está desarrollada bajo “código abierto” (esto es, que un usuario o desarrollador quiera y pueda acceder al código del programa), que éste esté claro y, a ser posible, comentado.

– Lo ideal es que todos los programas estén preparados para TODOS los idiomas que existen. Pero, ante tamaña idea, lo más guay es que el programa y la documentación estén en dos idiomas. Se aconsejan la lengua nativa (la del programador) y otra más universal (por ejemplo, el inglés). Y si no, que por lo menos haya una breve nota documentativa en lenguage “universal”.

– Para el usuario son muy importantes los ejemplos prácticos. Si nuestro programa transporta datos desde un documento de texto hasta una base de datos, es una buena idea incluir un documento de texto y una base de datos, aunque sean sencillitos, que propongan un ejemplo viviente de lo que se puede hacer con la aplicación.

Update

Notas adicionales sobre técnicas de aceleración

Uno de los padres de la agilización y optimización de scripts, Nigel Garvey, propone varios métodos para acelerar la ejecución de procesos redundantes, que dan muy buenos resultados al procesar grandes cantidades de datos o de modo redundante (sobre todo en estructuras “repeat”). Cito alguno:

-Utilizar “referencias” para acceder a objetos en una lista o “record” (descubrimiento atribuido a Serge Belleudy-d’Espinose). Por ejemplo:

set x to {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9}

chrono –> comando de Smile para medir tiempo

repeat 500 times

set y to {}

repeat with i from 1 to count x

set y’s end to x’s item i

end repeat

end repeat

chrono –> 1.04 segundos

repeat 500 times

set y to {}

repeat with i from 1 to count x

set y’s end to my x’s item i

end repeat

end repeat

chrono –> 0.64 segundos

repeat 500 times

set y to {}

repeat with i from 1 to count x

set my y’s end to my x’s item i

end repeat

end repeat

chrono –> 0.37 segundos

Aquí vemos 3 ejemplos. El primero, lo que hacemos habitualmente, en este caso estamos simplemente copiando los elementos de x en y, de uno en uno (es una prueba de velocidad, no digo que sirva para nada). Tardamos 1.04 segundos en ejecutarlo 500 veces.

En el segundo caso, añadimos la palabra “my” para referirnos al “item i of x”. O sea, que estamos trabajando con una “referencia” (fe, amigos, fe), en vez de utilizar directamente el objeto “i of x”. Como vemos, hemos reducido el tiempo de ejecución a 0.64 segundos.

Y en el tercer caso, añadimos también la palabra mágica “my” para referirnos a la lista “y”. Y nos ponemos en 0.37 segundos.

-Particularmente efectivo cuando trabajamos con texto y necesitamos compararlo con otro, o similares, es utilizar una cláusula “considering case” (fe):

set x to items of “abcdefghijklmnopqrstuvwxyz”

chrono –> comando de Smile para medir tiempo

repeat 500 times

set y to {}

repeat with i from 1 to count x

set theItem to my x’s item i

if theItem is not in my y then set my y’s end to theItem

end repeat

end repeat

chrono –> 7.66 segundos

Aquí queremos (porque sí) copiar en “y” los item de “x” que no se encuentren en “y” (en este caso, se copiarán todos, porque son item originales, pero eso da lo mismo). Tenemos un tiempo de 7.66 segundos. Ahora apliquemos lo dicho:

set x to items of “abcdefghijklmnopqrstuvwxyz”

chrono –> comando de Smile para medir tiempo

considering case

repeat 500 times

set y to {}

repeat with i from 1 to count x

set theItem to my x’s item i

if theItem is not in my y then set my y’s end to theItem

end repeat

end repeat

end considering

chrono –> 2.58 segundos

-Hay alguna cosilla más, pero ya es para puristas. Por ejemplo, se supone que:

if “a” is not “b” then “c”

Es más lento que:

if “a” is “b” then

else

“c”

end if

Pero ya hablamos de milmillonésimas de segundo.

Un saludo a todos!

Los restantes artículos sobe AppleScript se pueden encontrar en la categoría de Tutorial

0 0 votos
Article Rating
Subscribe
Notify of
7 Comments
Oldest
Newest Most Voted
Opiniones Inline
Ver todos los comentarios
Anónimo
Anónimo
19 years ago

Existe algún sitio donde aparezcan juntos todos los cursos de Applescript publicados hasta la fecha? No logro dar con él.

Muy bueno, enhorabuena.

Anónimo
Anónimo
19 years ago

Los tienes en la categoría tutorial, Acid.

Anónimo
Anónimo
19 years ago

Notas adicionales sobre técnicas de aceleración
Uno de los padres de la agilización y optimización de scripts, Nigel Garvey, propone varios métodos para acelerar la ejecución de procesos redundantes, que dan muy buenos resultados al procesar grandes cantidades de datos o de modo redundante (sobre todo en estructuras “repeat”). Cito alguno:
-Utilizar “referencias” para acceder a objetos en una lista o “record” (descubrimiento atribuido a Serge Belleudy-d’Espinose). Por ejemplo:

set x to {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9}

chrono –> comando de Smile para medir tiempo

repeat 500 times
set y to {}
repeat with i from 1 to count x
set y’s end to x’s item i
end repeat
end repeat

chrono –> 1.04 segundos

repeat 500 times
set y to {}
repeat with i from 1 to count x
set y’s end to my x’s item i
end repeat
end repeat

chrono –> 0.64 segundos

repeat 500 times
set y to {}
repeat with i from 1 to count x
set my y’s end to my x’s item i
end repeat
end repeat

chrono –> 0.37 segundos

Aquí vemos 3 ejemplos. El primero, lo que hacemos habitualmente, en este caso estamos simplemente copiando los elementos de x en y, de uno en uno (es una prueba de velocidad, no digo que sirva para nada). Tardamos 1.04 segundos en ejecutarlo 500 veces.
En el segundo caso, añadimos la palabra “my” para referirnos al “item i of x”. O sea, que estamos trabajando con una “referencia” (fe, amigos, fe), en vez de utilizar directamente el objeto “i of x”. Como vemos, hemos reducido el tiempo de ejecución a 0.64 segundos.
Y en el tercer caso, añadimos también la palabra mágica “my” para referirnos a la lista “y”. Y nos ponemos en 0.37 segundos.

-Particularmente efectivo cuando trabajamos con texto y necesitamos compararlo con otro, o similares, es utilizar una cláusula “considering case” (fe):

set x to items of “abcdefghijklmnopqrstuvwxyz”

chrono –> comando de Smile para medir tiempo

repeat 500 times
set y to {}
repeat with i from 1 to count x
set theItem to my x’s item i
if theItem is not in my y then set my y’s end to theItem
end repeat
end repeat

chrono –> 7.66 segundos

Aquí queremos (porque sí) copiar en “y” los item de “x” que no se encuentren en “y” (en este caso, se copiarán todos, porque son item originales, pero eso da lo mismo). Tenemos un tiempo de 7.66 segundos. Ahora apliquemos lo dicho:

set x to items of “abcdefghijklmnopqrstuvwxyz”

chrono –> comando de Smile para medir tiempo

considering case
repeat 500 times
set y to {}
repeat with i from 1 to count x
set theItem to my x’s item i
if theItem is not in my y then set my y’s end to theItem
end repeat
end repeat
end considering

chrono –> 2.58 segundos

-Hay alguna cosilla más, pero ya es para puristas. Por ejemplo, se supone que:

if “a” is not “b” then “c”

Es más lento que:

if “a” is “b” then
else
“c”
end if

Pero ya hablamos de milmillonésimas de segundo.

Un saludo a todos!

Anónimo
Anónimo
18 years ago

un error muy comun es sumar cadenas de caracteres cuando realmente quieres sumar enteros !!!!
como se soluciona la suma de enteros?

Anónimo
Anónimo
18 years ago

Hola, Albert… ¿A qué te refieres con “sumar cadenas de caracteres”? Esto sería “concatenar”:
“2” & “3” –> “23”
Pero esto sí funciona…
“2” + “3” –> 5
(AppleScript convierte automáticamente el texto en número si se puede, al encontrar el operador “+”)
Y esto también funcionaría:
run script “2 + 3” –> 5

Anónimo
Anónimo
18 years ago

Hola, Albert… ¿A qué te refieres con “sumar cadenas de caracteres”? Esto sería “concatenar”:
“2” & “3” –> “23”
Pero esto sí funciona…
“2” + “3” –> 5
(AppleScript convierte automáticamente el texto en número si se puede, al encontrar el operador “+”)
Y esto también funcionaría:
run script “2 + 3” –> 5

Anónimo
Anónimo
18 years ago

sincronismo de su web !

7
0
Me encantaría saber tu opinión, por favor, deja un comentariox
()
x