2013-04-01 14 views
5

documentazione AppleScript suggerisce il seguente codice per costruire in modo efficiente un elenco:Come si costruisce in modo efficiente un elenco all'interno di un gestore in AppleScript?

set bigList to {} 
set bigListRef to a reference to bigList 
set numItems to 100000 
set t to (time of (current date)) --Start timing operations 
repeat with n from 1 to numItems 
    copy n to the end of bigListRef 
end 
set total to (time of (current date)) - t --End timing 

Si noti l'uso di un riferimento esplicito. Questo funziona bene al livello più alto di uno script o di un gestore di corsa esplicito, ma se si esegue lo stesso codice esattamente parola per parola all'interno di un altro gestore in questo modo:

on buildList() 
    set bigList to {} 
    set bigListRef to a reference to bigList 
    set numItems to 100000 
    set t to (time of (current date)) --Start timing operations 
    repeat with n from 1 to numItems 
     copy n to the end of bigListRef 
    end 
    set total to (time of (current date)) - t --End timing 
end buildList 
buildList() 

si rompe, producendo un messaggio di errore che dice, "può 'fare bigList nel tipo di riferimento. " Perché questa interruzione e qual è il modo corretto di creare in modo efficiente una lista all'interno di un gestore diverso da run()?

+1

Questo stesso problema si verifica (senza una risposta soddisfacente) qui: http://stackoverflow.com/questions/3569847/why-cant-applescript-make-firstvalue-of-hash-into-type-reference-in-this -test-c? rq = 1 – 108

+0

E più utile è questo: http://stackoverflow.com/questions/15777321/why-in-applescript-cant-you-declare-references-to-variables-local-to-handlers – 108

risposta

1

set end of l to i sembra essere più veloce di copy i to end of l:

on f() 
    set l to {} 
    repeat with i from 1 to 100000 
     set end of l to i 
    end repeat 
    l 
end f 
set t to time of (current date) 
set l to f() 
(time of (current date)) - t 

Si potrebbe anche usare un oggetto di script:

on f() 
    script s 
     property l : {} 
    end script 
    repeat with i from 1 to 100000 
     copy i to end of l of s 
    end repeat 
    l of s 
end f 
set t to time of (current date) 
set l to f() 
(time of (current date)) - t 

100000 è anche il limit of items that can be saved in compiled scripts, in modo otterrete un errore come questo se esegui lo script e prova a salvarlo come segue:

Il documento "Senza titolo" non può essere salvato come "Untitled.scpt".

è possibile mettere set l to f() all'interno di un gestore in modo l è locale, aggiunge set l to {} fino alla fine, o salvare lo script come .applescript.

1

Ecco i risultati e i metodi di un test di velocità che ho fatto qualche tempo fa. Si noti che il primo risultato in ogni prova è più lento perché lo script non è stato compilato in precedenza.

list_speed.xlsx

1

Aggiungendo "biglist globale" alla prima linea di buildList() ha fissato l'errore di compilatore. Sembra che all'interno del gestore di esecuzione, le variabili siano nude di default e l'operatore "un riferimento a" sia utile. Tuttavia, in altri contesti, le variabili sono già essenzialmente riferimenti indiretti e la creazione di un altro livello di riferimento interrompe le cose. La dichiarazione di una variabile globale in questi contesti rimuove il riferimento indiretto e consente all'operatore "un riferimento a" di funzionare, ma ciò non è necessario. Basta usare il riferimento indiretto predefinito.

Se questo non è chiaro, è perché non capisco completamente il meccanismo. Se hai una comprensione migliore di ciò che sta succedendo qui, si prega di commentare qui sotto.

Problemi correlati