They’re essentially the same technique: the list object being iterated over is passed into the repeat loop by reference, which confers two things: 1. the contents of the list is never evaluated in its entirety as it would be normally. Instead each item is evaluated only as and when its data is retrieved; and 2. an object’s data passed by value has had a copy of its data made, that serves as a snapshot of what that data looked like at that point in time. As it’s a copy, it means that any changes one makes to these data do not affect the original source. However, data passed by reference doesn’t copy the data; it passes the script a pointer to the address at which the data resides. Therefore, when we access these data, they’ll always reflect the data in its most current state; and any changes we make will be to the original source data.
On top of this, access times for list items passed by reference in AppleScript are–as you’ve seen–much, much quicker. Here’s another way to achieve the same thing:
set f to "/tmp/text.poo"
set sentences to the paragraphs of (read f)
repeat with sentence in a reference to my sentences
tell the sentence to if its length > 10 then ¬
set the contents to text 1 thru 5
end repeat
set text item delimiters to linefeed
set textContent to the sentences as text
set eof of f to 0
write the textContent to f
It’s practically identical to your script, but instead of creating a new variable to hold a reference to the list, I just created a reference to it in the declaration of the repeat loop. Here, the reference was created by the word my, which would have been sufficient for speed gains had we not needed to alter the contents of the original list. To make changes, though, a reference to is necessary, or one can use a script object:
script
property path: "/tmp/text.poo"
property list: paragraphs of (read path)
end script
tell the result
repeat with chunk in a reference to its list
tell the chunk to if its length > 10 then set the contents to text 1 thru 5
end repeat
set my text item delimiters to linefeed
set textContent to its list as text
set eof of (its path) to 0
write the textContent to its path
end tell
I got my powers of 2 wrong when creating my text.poo file, which accidentally ended up containing 256,000 lines. It only took about three seconds to read from and write it back to the file.
On a minor note, I’ve observed virtually everyone on this site religiously saving the old tids and then restoring them back afterwards, which I get the sense is something being doing because everyone else is seen to do it. It really isn’t necessary. I think Shane’s gone over this before, but it’s a left-over mantra from back when scripts used to all run within a single AppleScript instance. Now, at least for Script Editor, Script Debugger, and any program calling out to osascript (Alfred, BTT, Keyboard Maestro), this is not the case. The one program I’m aware of (because I use it) that does run successive scripts in a single instance is FastScripts.
Regardless, I would say that a better Good Practice habit to get into would be to forget about storing and resetting them, but always be conscientious to explicitly set the tids immediately before any line in a script that splits text using text items, or joins list items through coercion to text. It uses fewer lines of code; is more readable; it ensures one always stays aware of when these text transformations are taking place; and it alleviates any need to worry about someone else’s script, and whether or not they could have “forgotten” to reset their tids, leaving one free to focus on taking care of their own code in front of them.