Re: what is the best way to 'unset' a variable
Re: what is the best way to 'unset' a variable
- Subject: Re: what is the best way to 'unset' a variable
- From: John W Baxter <email@hidden>
- Date: Sat, 23 Mar 2002 15:30:30 -0800
At 0:07 -0800 3/23/2002, Bill Hoffman wrote:
[The doubly quoted part is from Baxter]
>
> If a global is large (a long string, etc), then there is an advantage to
>
> clearing it before reaching the end of the script: the script file on
>
> disk
>
> will be smaller if the large string is "cleared" than if it isn't. I
>
> think: experiment.
>
>
my question stems actually from the 'open file' thread.
>
>
say I'm rewriting a large-ish file or files, and inserting new content
>
at the beginning of the file. I'm first reading the entire file into a
>
temp variable with 'read file'. I then write my new content at the
>
beginning of an empty file, write the whole file chunk from the file
>
read temp variable into the file after that, close up and my new file is
>
written. I'm talking about large files in the MB size range.
>
>
now I've got a temp variable (or I could have several of them) with the
>
contents of an entire file in it hanging around that I no longer need or
>
want. I was of the impression (apparently a wrong one) that 'unsetting'
>
this temp variable once its useful life is over during the run time of
>
the script would free up memory or otherwise contribute to efficiency in
>
some way other than just anal tidiness, particularly if the variable(s)
>
in question are huge.
>
>
I was also thinking along the lines of something like a script object
>
'destructor' function (just clearing a script object variable outright)
>
for the same reasons. (I can just see the "why would you want to do
>
that?" replies coming on that).
>
>
I guess the question I should have asked is: does it provide a useful
>
benefit to 'unset' or clear a variable's data during runtime in
>
AppleScript, not what's the cleverest way to do it.
I spent some time kicking the tires of this script (Mac OS 9.1, AppleScript
1.6).
[If a line looks like a wrapped line, it's a wrapped line...read question 4
below before trying the script.]
-- Throw away memory usage tester.
on run
global g
local l2
display dialog "Check memory use"
activate application "Finder"
delay 30
beep
runTest()
display dialog "Test global?" buttons {"Yes", "No", "Cancel"}
default button "No"
if button returned of the result is "Yes" then
set g to buildString()
end if
display dialog "Test run handler local?" buttons {"Yes", "No",
"Cancel"} default button "No"
if button returned of the result is "Yes" then
set l to buildString()
end if
display dialog "Test run handler declared local?" buttons {"Yes",
"No", "Cancel"} default button "No"
if button returned of the result is "Yes" then
set l2 to buildString()
end if
end run
on runTest()
set a to buildString()
set ans to display dialog "Check memory use" buttons {"Empty",
"Don't Empty", "Cancel"} default button "Empty"
activate application "Finder"
delay 30
beep
if button returned of ans is "Empty" then
set a to ""
display dialog "Check memory use"
activate application "Finder"
delay 30
beep
end if
set b to buildString()
set c to buildString()
display dialog "Check memory use"
activate application "Finder"
delay 30
beep
return "OK"
end runTest
on buildString()
set aSeed to "abcdefghijklmnopqrstuvwxyz123456"
copy aSeed to s
repeat 15 times
copy s & s to s
end repeat
--display dialog (count of s) -- trust me, it's one meg
return s
end buildString
You might very well ask:
1. Why the "extra" handler runTest?
2. Why two forms of testing of local variables in the run handler?
The answers are related. In early testing, with the run handler
containing what the runTest handler does now (but without the variable c) I
noted that the size of the applet on disk increased after the first run of
the script. Further testing reminded me of what I already knew from before:
Point 1: in an applet, a variable used in the run handler acts like a
global variable in terms of being stored on disk after the applet runs,
UNLESS it is explicitly declared to be local.
So, I made the "extra" runTest handler, where the implicitly-local
variables are really local. I also made the ability in the run handler to
try declared globals, declared locals, and "implicitly globalish locals."
3. Why does runTest return "OK".
a. Why not? ;-)
b. Because when runTest was still run, and it didn't have the return
or a bunch of the code, the implicit return at the end of the run handler
returned the one-meg string. And ScriptDebugger 3.0 on Mac OS 9.1 spent
several minutes formatting it for the Script Result window (or at least
doing SOMETHING with it before the result appeared in the Script Result
window). "OK" was therefore quicker. A quick test on Mac OS 10.1.3 showed
no delay at all at that stage...the start of the result just appeared
(Script Debugger 3.0.1).
4. What do I do with this script?
a. Save it as an applet WITHOUT HAVING RUN IT. Here, it's called
memTest3...name as you like.
b. Verify that the applet is about 12K in size (Finder).
c. Make a copy of the applet.
d. Open Finder's About this Computer window and position where you can
click on some part of it.
e. Turn on balloon help.
f. Run the applet; each time it suggests checking memory, click on the
About this Computer window and hover the mouse over the memory usage bar
for the applet. Note the memory usage (mentally or, if like me, on paper,
or if organized, neatly on paper marked which what you did to get to that
point). The applet should have some "activate me" commands...note that you
can get back into the applet by double clicking the memory bar in About
this Computer, so I didn't bother adding them.
g. Exercise the "Empty" and "Don't" empty choices. Exercise the
various choices in the end game.
h. After each run, note the application size on disk. At least once
after enlarging the applet with the global variable, run again and note the
first memory usage number...it's no longer in the low hundreds. But when
you want a "pristine" copy of the applet, toss out the one you've enlarged
and make a new copy. [The other easy way to shrink the applet is to copy
the source code into a fresh script window and Save As... again. The copy
is easier.]
5. OK, so why does one one-meg string use 3 meg of memory?
I think it goes like this: for at least an instant, three copies of
the string exist.
a. the copy made in the buildString handler
b. the copy the handler returned
c. the copy in the variable
The first two of these get garbage collected quickly, but not "quickly
enough". AppleScript does not give memory back to the memory manager once
it has asked for the memory...it manages the memory itself. So to the
About this Computer application, the memory usage is what it was at the
instant the three copies existed.
6. Why did you make both of the variables b and c?
Because of the reuse of the memory briefly occupied by 5a and 5b. The
"Don't" empty and the "Empty" choices show the same memory usage if I only
have the variable b.
7. Why did you use such silly variable names?
Because this is a throw away script. And I didn't want to waste time
dreaming up meaningful names for the variables.
8. Why is a raven like a writing desk?
This is left as an exercise for the reader.
--John
--
John Baxter email@hidden Port Ludlow, WA, USA
_______________________________________________
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.