Que audaz afirmar AppleScript ser ineficientes (término vago) como una causa. Por supuesto, que muy bien podría ser un factor, pero se siente un poco raro decir que el guión es ineficiente, y lamentablemente así. No sé si esa es la única razón por la secuencia de comandos se ejecuta lentamente, pero es un buen lugar para empezar a hacer las correcciones, que describiré por la extracción de líneas problema en tu código:
⚠️ set myPeople to people
Redundante. Hay un pequeño punto en la asignación de un valor a una variable que no tiene intención de utilizar de una manera significativa (por ejemplo, para la manipulación de los datos sin cambiar la fuente, o, si usted realmente necesita, para hacer scripts más fáciles de leer o de depuración). En ningún otro lugar en su secuencia de comandos de hacer una referencia a myPeople
, excepto para la otra línea que también es redundante. Por lo tanto, no pierdas una operación (y, potencialmente, de la memoria, pero no realmente en este caso en particular) la creación de una variable que no es necesario.
⭕️ set numPeople to (count of myPeople)
Redundante en principio (me tenga en cuenta que registro el valor de numPeople
, a pesar de que sólo se utiliza para darle un índice de referencia, que usted no necesita saber; ver siguiente comentario).
⚠️ repeat with i from 1 to numPeople
set myGuy to item i of myPeople
Ignorando por un momento el registro de la llamada que hace referencia a numPeople
, entonces el propósito de la declaración numPeople
es permitir que la iteración a través de una lista por medio de una variable de contador (i
en su caso) que se utiliza para acceder a cada elemento a través de su índice (posición), es decir, item i of myPeople
. Hay muchos casos donde esto sería muy apropiado, pero es más lento que dejar de AppleScript preocuparse acerca de cómo se accede a los elementos de la lista, que se puede tomar en las manos el uso de esta sintaxis: repeat with myGuy in people
⚠️ set urlNum to count of personUrls
Redundante, por la misma razón que el anterior. Como una nota adicional, creo personalmente que elija para evaluar el tamaño de una lista mediante el length
de la propiedad. Esto no se aplica a las listas anidadas de listas para el que desea incluir profundamente los elementos anidados en el número final, pero ese no es el caso aquí.
Tan pronto como una secuencia de comandos se ha evaluado (recuperar) de un objeto, sus propiedades se han recuperado como parte de esa evaluación. length
es una propiedad de un objeto de la lista, y es una simple, unarios valor ( integer
), por lo que el acceso a ese valor siempre será rápida. count
es un comando. Realiza algunos no revelado operaciones(s) y devuelve un valor. No sé lo que esas operaciones son, y se llevará a cabo en el C-nivel de idioma, así que probablemente (casi seguro) no son el retraso de esta secuencia de comandos de abajo del todo. Pero, en principio, es algo a tener en cuenta, ya que hay otras situaciones† un comando y una propiedad aparentemente hacen lo mismo, pero la propiedad es demostrablemente más rápido.
†No recuerdo ahora mismo.
⭕️ if urlNum > 0 then
Redundante, en principio. Hay un else
cláusula que usted puede ser que insisten en mantener, pero la única cosa que lo hace para registrar el hecho de que no se ha hecho nada. Si alguien me preguntó cómo intencionalmente lento una secuencia de comandos de abajo porque es demasiado eficiente, esto podría ser uno de mis respuestas.
⚠️ repeat with j from urlNum to 1 by -1
Este está marcado por tanto el uso de una variable de contador, j
, y por su posición dentro de la if
bloque. Si urlNum
se establece en 0, la repetición de bucle de escuchar nunca habría entrado, y el script seguirá ejecutando el código que sigue. Pero, como se pondrá de manifiesto, la totalidad de la repeat
bloque es redunant.
⚠️ log ... (the label of item j of personUrls))
delete item j of personUrls
Estoy cuestionando la necesidad de este log
comando como un todo. Ciertamente no es tan contraproducente como la que mencioné antes, pero sí realizar una current date
comando de llamada, y una búsqueda en la personUrls
objeto de la lista.
- En situaciones donde se requieren una variable de contador para iterar a través de una lista, hacer como hizo anteriormente, y declarar una variable a la que puede asignar el elemento de lista actual del valor, es decir,
set hisURL to item j of personalUrls
. En crudo términos, cada vez que le AppleScript para [el valor de] item j of...
, se debe acceder a la lista de objetos y realizar una mirada hacia arriba, que es una operación relativamente costosa de realizar. La declaración de una variable significa que la búsqueda se realiza sólo una vez, entonces el valor de (una copia de la original) es almacenado en la memoria, para que la recuperación es rápida y fácil en términos computacionales.
Volviendo a el valor que se registra, su valor parece que se niega, por la supresión inmediata de los datos de direcciones URL. Me pregunto si usted podría tener sólo quería un medio de seguimiento en su secuencia de comandos habían alcanzado en su ejecución, los cuales no tienen que ser tan involucrado. El uso de su contador de variables, usted podría simplemente: log [j, i]
(registro de sus límites superior una vez es suficiente, ya que los valores no cambian durante un bucle).
El delete
comando, cuando se ve en el contexto de la repetición del bucle en el que se llama, va a ser de frenar las cosas un montón. Usted está iterando a través de cada elemento de una colección con el fin de eliminar...
⚠️ save
...luego de guardar los cambios. ¿Cómo puedo intencionalmente hacer mi script se ejecute tan lentamente como sea posible ? Me gustaría realizar una operación de guardar en la libreta de direcciones completa un número de veces igual a numPeople * urlNum
. Este valor es al menos 177, pero en realidad múltiplos de este. El número total de veces que usted necesita para realizar el save
de la operación, me imagino, sería de 1.
Los Efectos En Cadena:
Ahora sabemos que iterando PersonUrls
no era necesario, toda la repeat
bloque puede ser reemplazado con la línea: delete every url of myGuy whose...
.
- Como algo a ser consciente de, cualquier secuencia de comandos que funciones anidadas
repeat
bucles va a ser ineficiente: el número de operaciones realizadas es un producto de cada una de las listas del tamaño.
De hecho, me tenga en cuenta que usted hace mención de intentar eliminar un contacto de la Url en masa, que no funciona para usted, lo que le obliga a hacerlo de forma iterativa. Sin embargo, como no proporcionar cualquier código que muestra los métodos que se trató de hacer la masa de la eliminación, no es posible ofrecer una idea de por qué ha fallado para usted.
La eliminación de la repeat
bloque tiene un acumulado en beneficio de la negación de los padres if
bloque, independientemente de mis anteriores comentarios.
- Los condicionales pueden ser costosos expresiones a evaluar, en particular, la realización de 177 de ellos que nunca fueron necesarios.
El Refactorizado El Código:
Continuando hacia arriba a través de la secuencia de comandos, la variable anterior declaraciones de todos a ser redundante, lo que lleva a la eventual conclusión de que toda la secuencia de comandos es funcionalmente equivalente a:
use application "Contacts"
tell (a reference to every person)
delete (its urls where the value contains "outlook")
set its note to missing value
end tell
save
Sistema de información: AppleScript versión: 2.7 Sistema de versión: 10.13.6
¿Y Ahora Qué ?
Era su objetivo final para eliminar todas las Url que contengan "outlook", o ¿va a seguir con una "outlook" de la dirección URL para los contactos que tienen ellos ?