Another technique:
parts = {};
rc = Pat Match( "1234567890abcdefghijklmnopqrstuv", Pat Repeat( Pat Len( 4 ) >> parts[N Items( parts ) + 1] ) );
Show( parts );
parts = {"1234", "5678", "90ab", "cdef", "ghij", "klmn", "opqr", "stuv"};
Jim's approach is better for short strings because the next person that maintains the JSL will understand it. For strings that are 10K or so, the pattern matching will be noticably faster.
The pattern match (red curve) avoids reprocessing the string
The is the JSL to make the graph...
dt = New Table( "Untitled",
Add Rows( 0 ),
New Column( "n", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) ),
New Column( "forloopTime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) ),
New Column( "patternTime", Numeric, "Continuous", Format( "Best", 12 ), Set Selected, Set Values( [] ) )
);
For( nstr = 1, nstr < 10000, nstr *= 2,
dt << addrows( 1 );
dt:n = nstr * 4; // four substrings in the repeat...
TheString = Repeat( "abcd1234cdef5678", nstr );
start = Tick Seconds();
TheList = {};
i = 1;
While( Substr( TheString, i, 4 ) != "",
Insert Into( TheList, Substr( TheString, i, 4 ) );
i = i + 4;
);
stop = Tick Seconds();
dt:forloopTime = (stop - start);
start = Tick Seconds();
parts = {};
rc = Pat Match( theString, Pat Repeat( Pat Len( 4 ) >> parts[N Items( parts ) + 1] ) );
stop = Tick Seconds();
dt:patternTime = (stop - start);
Wait( 0 );
);
dt << Graph Builder(
Size( 764, 624 ),
Show Control Panel( 0 ),
Legend Position( "Inside Left" ),
Variables( X( :n ), Y( :forloopTime ), Y( :patternTime, Position( 1 ) ) ),
Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 9 ) ), Smoother( X, Y( 1 ), Y( 2 ), Legend( 10 ) ) ),
SendToReport(
Dispatch( {}, "n", ScaleBox, {Min( -1453.48837209302 )} ),
Dispatch( {}, "forloopTime", ScaleBox, {Format( "Best", 12 ), Min( -0.949803149606299 )} ),
Dispatch( {}, "graph title", TextEditBox, {Set Text( "Compare algorithms" )} ),
Dispatch( {}, "X title", TextEditBox, {Set Text( "n patterns " )} ),
Dispatch( {}, "Y title", TextEditBox, {Set Text( "Seconds" )} ),
Dispatch( {}, "400", LegendBox, {Set Title( "" )} )
)
);
The reason the for loop example slows down on large strings: the substr function must find the location of each substring, starting from the beginning. The pattern match moves through the string once.
Craige