Page History
SRP Fast Arrays are an alternative replacement to BASIC+ dynamic arrays and can greatly enhance performance for large processes. SRP_FastArray provides the following services:
Method | Description | Added |
---|---|---|
Clear | Removes all values from an SRP Fast Array. | 2.1.10 |
SRP_FastArray_Count | Counts the number of fields, values, or subvalues in an SRP Fast Array. | |
SRP_FastArray_Create | Creates a new SRP Fast Array. | |
SRP_FastArray_Delete | Performs a DELETE on an SRP Fast Array. | |
SRP_FastArray_Extract | Performs an EXTRACT on an SRP Fast Array. | |
SRP_FastArray_GetVariable | Converts an SRP Fast Array back into a BASIC+ dynamic array. | |
SRP_FastArray_Insert | Performs an INSERT on an SRP Fast Array. | |
SRP_FastArray_InsertFromList | Inserts an SRP List into an SRP Fast Array. | |
Match | Finds the first element to match a given string. | |
Reduce | Creates a new fast array containing only those elements that match the given string. | |
SRP_FastArray_Release | Releases the handle to an SRP Fast Array. | |
SRP_FastArray_Replace | Performs a REPLACE on an SRP Fast Array. | |
SRP_FastArray_ReplaceWithList | Replaces an element in an SRP Fast Array with an SRP List. |
...
Code Block |
---|
Array = Insert(Array, 2, 0, 0, "BASIC+") |
If you have a For loop that is inserting thousands of elements into a dynamic array, then BASIC+ is reallocating memory and rewriting your array thousands of times also. This kind of operation is expensive performance wise.
...
Code Block |
---|
ArrayHandle = SRP_FastArray_("Create(") |
Or you can create an SRP Fast Array initialized to a BASIC+ dynamic array, like this:
Code Block |
---|
ArrayHandle = SRP_FastArray_Create(("Create", "My":@FM:"Dynamic":@FM:"Array") |
...
Code Block |
---|
Value = SRP_FastArray_Extract(("Extract", ArrayHandle, 3, 0, 0) |
SRP Fast Array _FastArray simply grabs element three and returns it. Inserts, Deletes, and Replaces are all equally fast for similar reasons. SRP Fast Array _FastArray never needs to recopy its elements. An insert simply places the new value as a new string right where it needs to go.
Code Block |
---|
SRP_FastArray_Insert(("Insert", ArrayHandle, 2, 0, 0, "BASIC+") |
...
Code Block |
---|
Array = SRP_FastArray_GetVariable(("GetVariable", ArrayHandle) |
This function does allocated memory for the entire dynamic array and copies each element—with delimiters—into it. Obviously, if you call this method thousands of times, then you're no better off than when you were using a BASIC+ dynamic array. The idea is to manipulate your array using SRP Fast Array _FastArray and then writing it out when you are done.
There is always one more step when using SRP Fast Arrays. You have to release the handle.
Code Block |
---|
SRP_FastArray_Release(("Release", ArrayHandle) |
Sure, it's an extra step, but the performance gains are usually worth it. If you forget to do this, SRP Utilities will clean up all unreleased handles when OpenInsight closes, but if you plan on your application running for hours at a time, you still want to avoid memory getting used up and never freed.
...
Code Block |
---|
ArrayCount = SRP_FastArray_Count(("Count", Handle, 0, 0) |
Counting elements in an SRP Fast Array is instantaneous because field, value, and subvalue counts are all cached.
...
So far, all the samples have been dealing with field-mark delimited arrays. However, SRP Fast Array _FastArray supports three dimensional arrays as well. As previously stated, SRP Fast Array _FastArray emulates the Insert, Delete, Replace, and Extract methods of BASIC+ to the fullest. In fact, the deeper and more complex your dynamic array, the more performance you will get from SRP Fast Array_FastArray.
You can still place other delimiters into fields, values, and subvalues, but those other delimiters will just be treated like regular characters. This, of course, is no different than BASIC+.
When to Use SRP
...
_FastArray
As with everything, use the right tool for the right job. There are two factors to consider: the size of the dynamic array and the number of operations you intend to do upon it. The smaller the dynamic array, the less amount of time BASIC+ spends scanning, allocating, and copying. Also, even if you have an array that takes up several megabytes in memory, if you are only doing two extracts, SRP Fast Array _FastArray won't make that much of a difference.
Perhaps the best rule of thumb is this: if you have a process that takes a long time to run, look to see how much dynamic array manipulation it is doing. If there appears to be a great deal of it, then try out SRP Fast Array _FastArray and see if you get an improvement. Benchmark the differences to see if the increase in code complexity (SRP Fast Array methods _FastArray services are, after all, not as pretty as angle bracket operators) seems worth the performance gain, then huzzah! Some of us at SRP Computer Solutions have managed increase a routine's performance by a factor of ten!
When Not to Use SRP
...
_FastArray
There is one situation in which SRP Fast Array _FastArray does not seem to offer any significant performance increase: appending values. If your routine is only appending values at the end of the array and your dynamic array is only 1-dimensional, then BASIC+ is plenty fast for you. Essentially, BASIC+ dynamic arrays begin to suffer in performance when you perform random access, and inserting appending values in to a single-dimensioned array is not random access.
...
Code Block |
---|
Compile function Test_FastArray(VOID) $Insert SRPFASTARRAY // OI routines Declare function GetTickCount Declare subroutine Msg // SRP Fast Array routines Declare function SRP_FastArray_Create, SRP_FastArray_GetVariable, SRP_FastArray_Extract, SRP_FastArray_Count Declare subroutine SRP_FastArray_Release, SRP_FastArray_Insert, SRP_FastArray_InsertFromList, SRP_FastArray_Replace, SRP_FastArray_ReplaceWithList, SRP_FastArray_Delete Iterations = 10000 ; // How many operations to perform MaxPos = 100 ; // The maximum field, value, or subvalue position InsertText = "SRP Computer Solutions, Inc." ; // The text to insert InitRnd Time():Date() // Insert the text at random field, value, and subvalue positions StartTime = GetTickCount() TestOI = "" For i = 1 to Iterations TestOI = Insert(TestOI, Rnd(MaxPos), Rnd(MaxPos), Rnd(MaxPos), InsertText) Next i InsertTimeOI = GetTickCount() - StartTime // Insert the text at random field, value, and subvalue positions using SRP Fast Array_FastArray StartTime = GetTickCount() Handle = SRP_FastArray_("Create(") For i = 1 to Iterations SRP_FastArray_Insert(("Insert", Handle, Rnd(MaxPos), Rnd(MaxPos), Rnd(MaxPos), InsertText) Next i TestSRP = SRP_FastArray_GetVariable(("GetVariable", Handle) InsertTimeSRP = GetTickCount() - StartTime // Extract values at random field, value, and subvalue positions StartTime = GetTickCount() For i = 1 to Iterations A = Extract(TestOI, Rnd(MaxPos), Rnd(MaxPos), Rnd(MaxPos)) Next i ExtractTimeOI = GetTickCount() - StartTime // Extract values at random field, value, and subvalue positions userusing SRP Fast Array_FastArray StartTime = GetTickCount() For i = 1 to Iterations A = SRP_FastArray_Extract(("Extract", Handle, Rnd(MaxPos), Rnd(MaxPos), Rnd(MaxPos)) Next i ExtractTimeSRP = GetTickCount() - StartTime // Clean up the memory SRP_FastArray_Release(("Release", Handle) Msg(@Window, "OI Insert Time: ":InsertTimeOI:"ms|SRP Insert Time: ":InsertTimeSRP:"ms||OI Extract Time: ":ExtractTimeOI:"ms|SRP Extract Time: ":ExtractTimeSRP:"ms") Return 1 |
...
Code Block |
---|
Locate Target in Array<2, 10> using @SVM setting Pos then end |
SRP Fast Array _FastArray does not have built in searchinga Locate service, but SRP List does. Thankfully, SRP Lists can be created instantaneously from SRP Fast Arrays using a special method. So, we can do a locate at blinding speeds after all:it does have the Match and Reduce services. The Match service looks for an element that matches (in part or in total) a given string and gives you the position of the first match. The Reduce service finds all elements that match a string and return a reduced array containing only those elements.
Code Block |
---|
Pos |
Code Block |
ListHandle = SRP_List_CreateFromFastArray(ArrayHandleFastArray("Match", Handle, 2Target, 10) Pos = SRP_List_Locate(ListHandle, Target) SRP_List_Release(ListHandleFieldPos, ValuePos, SubValuePos, "MatchAll") |
Inserting SRP Lists
SRP Fast Arrays play nicely with SRP Lists. In addition to using Insert and Replace on single values, you can also insert SRP whole SRP Lists or replace elements with whole SRP Lists. Since SRP Lists have no delimiter recognitions at all, they will behave as though they are delimited one level lower than the insert level. So, if you insert an SRP List into a field position, the SRP List will behave as though it is value-mark delimited.
...
Note that one major difference between the BASIC+ Insert, Delete, and Replace routines and the SRP Fast Array _FastArray equivalent routines services is that the BASIC+ routines always creates a new Array and returns it. SRP Fast Array _FastArray does not do this since creating copies is the performance bottle neck SRP Fast Array _FastArray is working to avoid.
Oh yeah, one more thing: don't forget to release your SRP Fast Array handles.