• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Top level garbage strike
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Top level garbage strike


  • Subject: Re: Top level garbage strike
  • From: Axel Luttgens <email@hidden>
  • Date: Sun, 12 Jan 2003 17:11:40 +0100

Steven Angier wrote:

Baffled by the diminishing performance of a script application I worked on
recently, I uncovered what I thought was an interesting garbage-collection
problem.

It seems that some types of top-level objects persist on the stack or heap
indefinitely. Take the following example:

script Something
property someProperty : {}
end script

on InitSomething()
local theInstance
copy Something to theInstance
return theInstance
end InitSomething

StartTicks()
set theTickList to {}
repeat 10 times
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set the end of theTickList to ResetTicks()
end repeat

return theTickList

--> {
2, 6, 12, 15, 20, 26, 31, 37, 44, 51
}

Run it again (without recompiling) and the times continue to grow:

--> {
60, 66, 68, 75, 86, 93, 103, 117, 120, 128
}


I think you may simplify your example as follows:

-- Script1

script Something
property someProperty : {}
end script

repeat 100 times
copy Something to theInstance
end repeat

You should observe the same behavior with Script1 as with your orginal script, while things should appear more clearly.

On each iteration, you create a new copy of Something and store it into theInstance.
But that new copy includes Something as well as its parent (with its current status).
That is, consecutive copies get more and more complicated.

Consider this:

-- Script2

script Something
property someProperty : {}
end script

set theInstance to "xxx" -- for visualization purposes

copy Something to theInstance
theInstance
--> script
theInstance's theInstance
--> "xxx"

copy Something to theInstance
theInstance
--> script
theInstance's theInstance
--> script
theInstance's theInstance's theInstance
--> "xxx"

copy Something to theInstance
theInstance
--> script
theInstance's theInstance
--> script
theInstance's theInstance's theInstance
--> script
theInstance's theInstance's theInstance's theInstance
--> "xxx"

-- and so on...

By contrast, you may consider this:

-- Script3

script Something
property parent: AppleScript
property someProperty : {}
end script

repeat 100 times
copy Something to theInstance
end repeat

avoiding that way to carry over and over the top level script's context.


Though if you wrap the implicit run handler in a function, no problem:

on PerformLocalisedTest()
StartTicks()
set theTickList to {}
repeat 10 times
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set theInstance to InitSomething()
set the end of theTickList to ResetTicks()
end repeat
return theTickList
end PerformLocalisedTest

return PerformLocalisedTest()

--> {
0, 0, 0, 0, 0, 1, 0, 1, 0, 0
}


Because you now have made any variables local: no more contexts with growing complexities.


I presume that the increasing times are due to some internal runtime array
which is not cleared, and that AppleScript has to find/create space at the
end of the array when another object is created.



All this begs the question: when is top-level garbage ever collected? This
sort of thing can bog down a script very quickly. I know from experience
that in the scope of a tight repeat loop contained in a function,
AppleScript generally doesn't collect its garbage until the repeat loop is
finished -- although you can force (or allow) AppleScript to collect garbage
by calling another function from within the repeat loop. Clearly, this
scheme doesn't work at the top-level.

I'm not sure if this is a bug or known and accepted behaviour. Any insights?


Well, I believe the above explains much of what you observed.
And that all this results from explicitely defined behavior of scripts objects in relationship with the copy command.

But I wouldn't authoritatively discard some other problems. Who knows ;-)



AppleScript 1.9.1 / Mac OS X 10.2.3


Steven Angier
Macscript.com


HTH,
Axel
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: Top level garbage strike
      • From: Steven Angier <email@hidden>
References: 
 >Top level garbage strike (From: Steven Angier <email@hidden>)

  • Prev by Date: Opening a local HTML file in the default browser
  • Next by Date: Re: Forcing 'tell app' to use carbon, rather than classic app
  • Previous by thread: Top level garbage strike
  • Next by thread: Re: Top level garbage strike
  • Index(es):
    • Date
    • Thread