Applescript performanter machen?

The-Kenny

Transparent von Croncels
Registriert
22.05.08
Beiträge
307
Hallo,

Ich habe mir ein AppleScript geschrieben um mir meine ToDos aus Things mit geekTool auf dem Desktop anzeigen zu lassen.
Leider ist die Performance echt unterirdisch - 5sek Laufzeit und eine hohe Prozessorauslastung sind einfach nicht annehmbar.

Leider gehen mir die Ideen zum optimieren aus, was auch daraus resultiert, dass ich mich in Applescript nicht so gut auskenne.

Vielleicht kann sich ja jemand hier das Script ansehen:
Code:
global lineLimit
global lineCount
global noDuplicates
global alreadyShown

-- modify section 

set lineLimit to 36
set noDuplicates to true

-- end of modify section

set lineCount to 0
set alreadyShown to {}

on getListContents(aList, aLimit)
    tell application "Things"
        set fullReport to aList & "\n"
        set lineCount to lineCount + 1 -- We have started a new line
        set itemCount to 1
        
        repeat with aToDo in (to dos of list aList where status is open)
            if lineCount < aLimit then
                if noDuplicates and id of aToDo is in alreadyShown then
                else
                    
                    set fullReport to fullReport & (itemCount as string) & ".\t" & (name of aToDo) & "\n"
                    
                    set lineCount to lineCount + 1
                    set itemCount to itemCount + 1
                    
                    if noDuplicates then
                        set alreadyShown to alreadyShown & (id of aToDo)
                    end if
                end if
            end if
        end repeat
        
        return fullReport
    end tell
end getListContents

set today to getListContents("Today", lineLimit) & "\n"
set lineCount to lineCount + 1
set next to getListContents("Next", lineLimit - lineCount)

return today & "\n" & next
Natürlich darf jeder der möchte das Script für sich verändern und nutzen.

Meine zweite Idee wäre, das Script in einer anderen Sprache mit Osascript-Bindings zu schreiben. Aber ich bin mir nicht sicher ob sich das lohnt, und ob das Bottleneck nicht doch die Anwendung ist.
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Du kannst die AppleScript Bridge in Cocoa verwenden, die holt da einiges Raus.

Ob das Bottleneck aber nicht die App ist, kann ich Dir nicht sagen

Alex
 

The-Kenny

Transparent von Croncels
Registriert
22.05.08
Beiträge
307
Cocoa überrascht mich doch immer wieder - ScriptingBridge ist mir vorher noch nie begegnet, sieht aber echt super aus. Da macht es gleich richtig Spaß das Script in Obj-C zu schreiben.

Vielen Dank,
The-Kenny
 

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
Hallo,

ich arbeite seit ca. einem Jahr mit den SB.
Das bereitet viel Spass und ist um ein vielfaches schneller.
Zudem kannst Du zu berechnende Aufgaben besser verschieben.

Code:
tell application "iTunes"

	set theName to name of current track
	
		-- manipuliere Namen

	set name of current track to theName
end

Hier würde jetzt alles von iTunes erledigt werden.
Wenn Du den Namen aber in Deiner eignen Applikation manipulierst, dann werden nicht unnötigerweise Events versandt.
Aber das bekommst Du schnell selbst heraus...
Mit der SB ist das sehr schön umzusetzen.

Zu Deinem Skript:

Code:
repeat with aToDo in (to dos of list aList where status is open)
Ohne den Hintergrund zu kennen, so ist dass das Schlimmste was mit AS machen kann.
In einer Schleife jedes Mal eine komplette Abfrage.
Du fragst einmal ab und läufst dann die Liste (in einer Variablen gesichert) ab.
Das ist ein immenser Unterschied.


Code:
repeat with nTrack in (every track of library playlist 1)

	-- nTrack abarbeiten

end

"every track of library playlist 1" braucht bei mir ca. 60 Sekunden um ermittelt zu werden.
Dann entsteht eine Liste mit 30.000 Einträgen. Diese Abfrage wird bei jedem Durchgang erstellt.
60 Sekunden multipliziert mit 30.000 Einträgen ist dann die Summe der Mindestlaufzeit.

Schlauer ist:

Code:
set allTracks to every track of library playlist 1

repeat with nTrack in allTracks

	-- nTrack abarbeiten

end
Das ist eine Abfrage.

Wenn Du Dich zum Thema SB einliest, dann wirst Du genau auf dieses "Problem" von Apple hingewiesen.

http://developer.apple.com/document...ef/doc/uid/TP40006104-CH6-DontLinkElementID_6

Viele Grüße
 
  • Like
Reaktionen: below

pepi

Cellini
Registriert
03.09.05
Beiträge
8.740
Warum denn AppleScript wo doch Things alles als XML speichert? Da kann man doch mit einem Shellscript in Python vergleichsweise leicht dran kommen und da ist die Performance wohl auch besser.
Gruß Pepi
 

The-Kenny

Transparent von Croncels
Registriert
22.05.08
Beiträge
307
Ohne den Hintergrund zu kennen, so ist dass das Schlimmste was mit AS machen kann.
In einer Schleife jedes Mal eine komplette Abfrage.
Du fragst einmal ab und läufst dann die Liste (in einer Variablen gesichert) ab.
Das ist ein immenser Unterschied.
Das wusste ich nicht. Ich dachte AppleScript wäre so schlau nicht jedesmal eine komplette Abfrage zu machen, aber egal, darum brauch ich mich nicht mehr zu kümmern ;)

Mit der ScriptingBridge läuft das ganze nun in weit unter einer Sekunde und ist meiner Meinung nach schöner anpassbar. Danke an alle.

(Das einzige was mich wundert ist, dass das Programm eine Exception wirft sobald ich gcc optimieren lasse. Er sendet eine Messsage an das ThingsApplication-Objekt, anstatt an eine meiner Klassen)

Warum denn AppleScript wo doch Things alles als XML speichert? Da kann man doch mit einem Shellscript in Python vergleichsweise leicht dran kommen und da ist die Performance wohl auch besser.
Gruß Pepi

Da gibts einige Gründe:
Hast du dir mal das .xml angesehen? Das ist CoreData, tausend Cross-References, unendlich aufgebläht und mistig. Alleine ein einfaches "name of project of todo" ist da eine riesen Fummelei.

Auf dem iPhone ist es da einfacher. Dort ist es eine einfache sqlite-Datenbank. Siehe mein LockscreenInfo-Plugin für Things ;)