We could add a cache argument to Parse*(), and thus to *Message() and *Print(). This maps the format template (as the key) to the ParserElement array (as the value) that results from parsing format, all within a "dictionary" of modular scope.
If we are using the same format many times, and merely changing the data we embed, then cache := True will save plenty of time by parsing format once and for all, rather than reparsing it with every call. But we must explicitly opt into caching, otherwise we risk inflating the cache with many unique arrays.
Public Function xMessage( _
ByRef format As String, _
' ...
Optional ByVal cache As Boolean = False, _
' ...
) As String
' ...
End Function
Structure
It might be tricky to implement this cache, since Collections (and Variants) do not accommodate (arrays of) custom types like ParserElement. We must get creative to store these arrays both dynamically and efficiently.
Also, the keys of Collections are not case-sensitive. This is problematic, because various components of format are indeed case-sensitive, including plaintext and format codes. Perhaps we must do a lookup on the format.
Wrapper Type
One approach is to create a "wrapper" type like ParserResult.
Private Type ParserResult
Format As String
Elements As ParserElement()
End Type
Then we can create our cache without wasting space on a 2D array of ParserElements.
Private Type ParserCache
Results As ParserResult()
Count As Long
End Type
Now, we need only use Redim Preserve to expand .Results as a 1D array. In order to avoid inefficient resizing, we might use a "doubling algorithm", which resizes .Results to twice its original length, whenever we exceed that length.
We could add a
cacheargument toParse*(), and thus to*Message()and*Print(). This maps theformattemplate (as the key) to theParserElementarray (as the value) that results from parsingformat, all within a "dictionary" of modular scope.If we are using the same
formatmany times, and merely changing thedatawe embed, thencache := Truewill save plenty of time by parsingformatonce and for all, rather than reparsing it with every call. But we must explicitly opt into caching, otherwise we risk inflating the cache with many unique arrays.Structure
It might be tricky to implement this cache, since
Collections (andVariants) do not accommodate (arrays of) custom types likeParserElement. We must get creative to store these arrays both dynamically and efficiently.Also, the keys of
Collections are not case-sensitive. This is problematic, because various components offormatare indeed case-sensitive, including plaintext and format codes. Perhaps we must do a lookup on theformat.Wrapper Type
One approach is to create a "wrapper" type like
ParserResult.Then we can create our cache without wasting space on a 2D array of
ParserElements.Now, we need only use
Redim Preserveto expand.Resultsas a 1D array. In order to avoid inefficient resizing, we might use a "doubling algorithm", which resizes.Resultsto twice its original length, whenever we exceed that length.