How to replace just the first found space with tab for all lines in a variable?
Alex Tweedly
alex at tweedly.net
Thu May 26 06:32:53 EDT 2011
On 25/05/2011 16:48, Nonsanity wrote:
> And if this is a one-shot utility function, than any of these solutions that
> work for you are great. But if you will be doing this as a feature of a
> program, and the amounts of data you'll be pushing through are large, then
> modifying the data in-place saves time and memory over copying large
> quantities of text between two variables. Just sayin'. :)
That's true - in general, but not in this case.
The big exception is that "line a of myText" is quite expensive in LC.
In fact, it is VERY expensive, because the engine needs to scan the text
to find the line, which means that operations such as
> repeat with a = 1 to the number of lines in myText
> if space is not in line a of myText then next repeat
> put tab into char (offset( space, line a of myText )) of line a of myText
> end repeat
take time based on the square of the number of chars/lines in the data.
On the other hand, copying from one variable to another takes linear
time based on the number of chars/lines, and
repeat for each line L in myText
...
put theModifiedLine & CR after tOutputData
end repeat
is also linear (so long as it is "put xxx *after* tOutputData" because
simply appending is linear).
So, taking the benchmark that Jim recently sent, and adding the
alternative version which modifes it in place, we see that modifying in
place is very, very slow by comparison.
On my Macbook Pro, the "copy" method takes 1 tick while the "in place"
version takes around 820 (btw - I changed the number of lines down to
20000; estimated time for the original count would have been too slow).
--- working code ----
on mouseUp
trythisForSpeed
end mouseUp
on trythisForSpeed
put 20000 into weaponOfMassConstruction
repeat weaponOfMassConstruction times
get the seconds
put IT && IT && IT & cr after massiveList
end repeat
put the ticks into startt
repeat for each line tLine in massiveList
put word 1 of tLine& tab& word 2 to -1 of tLine& return after
tResultTable
end repeat
filter tResultTable without empty
put the ticks - startt into elapsedTks
if elapsedTks = 0 then
put "Too fast to measure 'cause it took less than 1 tick" & CR
else
put "elapsed =" && elapsedTks && "ticks thus" \
&& elapsedTks/60 && "seconds" & cr \
&& "or" && weaponOfMassConstruction/elapsedTks \
&& "address lines per tick" & cr \
&& "or approx" \
&& 60*(weaponOfMassConstruction/elapsedTks) \
&& "per second" & CR
end if
put the ticks into startt
repeat with I = 1 to the number of lines in massiveList
-- if space is not in line I of myText then next repeat
put tab into char (offset( space, line I of massiveList )) of
line I of massiveList
end repeat
put the ticks - startt into elapsedTks
if elapsedTks = 0 then
put "Too fast to measure 'cause it took less than 1 tick" & CR
after msg
else
put "elapsed =" && elapsedTks && "ticks thus" \
&& elapsedTks/60 && "seconds" & cr \
&& "or" && weaponOfMassConstruction/elapsedTks \
&& "address lines per tick" & cr \
&& "or approx" \
&& 60*(weaponOfMassConstruction/elapsedTks) \
&& "per second" & CR after msg
end if
end trythisForSpeed
More information about the use-livecode
mailing list