Tom,
what happens in tight repeat loops, especially when they are long, is they lock up the engine. This means the engine does only the repeat loops. On a Mac it does not even have the time to update the screen.
Often if you have an error in the repeat loop you cant abort the repeat loop with escape or command-period. You have to terminate Livecode from the system.
The remedy is to add a "wait 0 milliseconds with messages"." with messages" is the magic phrase here. This gives the engine room to do its housekeeping and makes the repeat loop interruptible and makes the stack responsive again. E.g you can move the stack around.
All that said I changed your script a bit to make it more efficient especially when you do high number of repeats.
I use an array and use the random number as a key of the array and put 1 into the array, so every time the same random number is generated 1 is added to the value of the key = random number. That way I can test if the number has been generated before since the value of it will be greater 1.
This has the advantage that you don't have to test a long list for an occurence of the random number. That is a lot to do for Livecode.
Currently I put the wait 0 milliseconds with messages into the conditional if a match has been found. That is also the moment of updating the screen. Less screen updating = more speed.
I took a couple of references to field values and put the into variables since those fields never change in the repeat loop.
BTW "add 1 to i" is faster than "put i + 1 into i"
for 100,000 iterations and UI update ever 10,000 and continuous update of the number of duplicates takes about 50 seconds on my machine. And the Livecode stays responsive.
Code: Select all
on mouseUp
local i,ii,mynum
global WholeList
put 1 into i
put 1 into ii
put empty into the field "list"
put empty into WholeList
put empty into the field "number of matches"
put empty into the field "counter"
lock messages
put field "how many possibilities" into tHowManyPossibilities
put field "how many repeats" into tHowManyRepeats
put field "update every" into tUpdateEvery
put the milliseconds into tStart -- remove when done with testing speed
// REPEAT
lock screen
repeat tHowManyRepeats
// generate number and feed it as key to an array
put random(tHowManyPossibilities) & "-" & random(tHowManyPossibilities) & "-" & random(tHowManyPossibilities) into mynum
-- here we fill an array with mynum as key and add 1 to the value of the key, the first time the value will be 1, second time (= same key = same random number) 2 etc
add 1 to tArray[mynum]
// check field update counter
if ii is tUpdateEvery then
put i into the field "counter"
put mynum into the field "current number"
put 0 into ii
else
end if
// check current number vs array, since we use mynum as key of the array
// and add 1 to the mynum if mynum has been added before the array contains at least 2
// that it the reason why we test for: if tArray[mynum] > 1
if tArray[mynum] > 1 then
put "Matched Number: " & mynum & return after tCollect
add 1 to tCounter
put tCollect into field "list"
put tCounter into field "number of matches"
unlock screen
wait 0 milliseconds with messages -- this lets Livcode update the screen and do some housekeeping
lock screen
end if
add 1 to i
add 1 to ii
--wait 0 milliseconds with messages -- this would be the place if you want to do it every time around the repeat loop
end repeat
put the milliseconds - tStart -- remove when done with testing speed
unlock screen
end mouseUp
Kind regards
Bernd