Results 1 to 8 of 8

Thread: clsBSTR - the ultimate string class

  1. #1

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    clsBSTR - the ultimate string class

    This is the first "full" release of this class. You've probably sometimes heard of StringBuilder classes or about cString class that offer a better performance for concatenating strings. This class does this, but it does it much better than other classes of this kind, being both easy to use and fast. Besides concatenation there are many more features included within this class.

    Sample syntaxes:
    Code:
    Dim strTemp As New clsBSTR
    
    strTemp = "Hello!"
    MsgBox strTemp
    ' output: the obvious
    
    MsgBox strTemp.SetValue("this line has LOTS OF STUFF!").PCase
    ' output: "This Line Has Lots Of Stuff!"
    
    MsgBox strTemp.SetValue("One?").Replicate(5)
    ' output: "One?One?One?One?One?"
    
    strTemp = "AAABCCC"
    strTemp.Middle(0, 3) = "_"
    strTemp.Middle(strTemp.Length - 3, 3) = "_"
    MsgBox strTemp
    ' output: "_B_"
    
    strTemp = "ABC"
    strTemp.Middle(2, 0) = "[surprise!]"
    strTemp.Middle(1, 0) = "[a big]"
    MsgBox strTemp
    ' output: "A[a big]B[surprise!]C"
    
    strTemp = "1|2|3|2|1|4|5|6|9|8|7|8|9"
    MsgBox strTemp.Trim "123789|"
    ' output: "4|5|6"
    This isn't a final release of the class: there is room for new features and for further optimizations, although at this point of performance the latter isn't just as important.

    This thread is open for feature requests and generic feedback. If you wish to talk about the optimization tricks or you have ideas on what could be done better, check the thread over at Code It Better forum.
    Attached Files Attached Files

  2. #2
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: clsBSTR - the ultimate string class

    Just saw this in your signature not too long ago. I've been using a simple concatenation class I found (clsConcat) but I think I like yours better, especially since it has more features.

    I especially like the .Middle method.

  3. #3
    Junior Member
    Join Date
    Feb 2007
    Posts
    28

    Re: clsBSTR - the ultimate string class

    Quite a good job Merri I am sure i will find use for it sometime

  4. #4
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: clsBSTR - the ultimate string class

    This is pretty ambitious, though it has a pretty contorted set of methods and properties.

    Why do so many return a reference to the same object? Was this meant as some aid to packing in multiple operations per line of code? Sort of like building a String expression or something?

    For my own use I find concatentation the main thing to worry about with String performance. I'm not so sure I would accept the tradeoff of something this complicated just to improve the rarer operations somewhat.

    If I need a reasonably fast "string builder" in VB 6 I simply use the ADO Stream object with it's Type set to "text." Benchmarks can be clumsy because once we get past using String concatenation itself most methods involve some fairly small timings, and most timers you can benchmark with have fairly lousy resolution.

    Here's an example timed using VB Watch 2 (attached).

    Contrary to what some people seem to think, the overhead of VB's For loops isn't bad at all. Of course timings are imprecise at these small values.

  5. #5

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: clsBSTR - the ultimate string class

    I tested compiled code with all advanced optimizations and both are pretty much of the same speed... until I made clsBSTR allocate a bit more space with BufferAllocSize

    Code:
    Option Explicit
    
    Dim STRADD As String
    Dim Q As clsTime
    
    Private Sub Command1_Click()
        Dim strOut As New ADODB.Stream, lngA As Long, strResult As String
        Q.Start
        strOut.Open
        strOut.Type = adTypeText
        For lngA = 1 To 10000
            strOut.WriteText STRADD
        Next lngA
        strOut.Position = 0
        strResult = strOut.ReadText
        strOut.Close
        Command1.Caption = "ADODB: (" & Len(strResult) & ") " & Format$(Q.GetTime * 1000, "0.000000")
    End Sub
    
    Private Sub Command2_Click()
        Dim strResult As New clsBSTR, lngA As Long
        Q.Start
        strResult.BufferAllocSize = 1000000
        For lngA = 1 To 10000
            strResult.Append STRADD
        Next lngA
        Command2.Caption = "clsBSTR: (" & Len(strResult) & ") " & Format$(Q.GetTime * 1000, "0.000000")
    End Sub
    
    Private Sub Form_Load()
        Set Q = New clsTime
        STRADD = Space$(100)
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        Set Q = Nothing
    End Sub
    Code:
    'clsTime.cls
    Option Explicit
    
    Private m_Freq As Double
    Private m_Start As Currency
    Private m_Stop As Currency
    
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
    Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    
    Public Function GetRemainingSeconds(ByVal CurrentValue As Long, ByVal EndVal As Long) As Currency
        Dim dblCurrent As Double
        If CurrentValue < 1 Then CurrentValue = 1
        If EndVal > CurrentValue Then
            QueryPerformanceCounter m_Stop
            dblCurrent = (CDbl(m_Stop - m_Start) / m_Freq)
            GetRemainingSeconds = CCur((dblCurrent / CurrentValue * EndVal) - dblCurrent)
        End If
    End Function
    Public Function GetTime() As Double
        QueryPerformanceCounter m_Stop
        GetTime = CDbl(m_Stop - m_Start) / m_Freq
    End Function
    Public Sub Start()
        QueryPerformanceCounter m_Start
    End Sub
    Private Sub Class_Initialize()
        Dim curFreq As Currency
        QueryPerformanceFrequency curFreq
        m_Freq = CDbl(curFreq)
    End Sub
    The result for ADODB in compiled is roughly one second on my machine, same for clsBSTR without changing allocation size, but with changed allocation it goes down to 6 ms. Under IDE it is at 15 ms.



    As for returning the object itself as a return value, it doesn't give too much performance loss, but it does give something that I personally consider useful (although concatenating short strings is faster to do with native strings).

    You can compile the class and the module into a DLL and make a reference to it: you get faster concatenation than with ADODB and you don't need a reference to it (of course, if you're already using ADODB for something else then it doesn't matter so much). ADODB method requires many extra lines to get the job done (Open, Type, Position, Close), which is something I also wanted to avoid. You can make the class lightweight by removing the features you don't need.
    Last edited by Merri; May 20th, 2007 at 04:00 PM.

  6. #6

    Re: clsBSTR - the ultimate string class

    How do you get operators in VB6 classes?

  7. #7
    Banned randem's Avatar
    Join Date
    Oct 2002
    Location
    Maui, Hawaii
    Posts
    11,385

    Re: clsBSTR - the ultimate string class

    Does this class build a string from a byte array?

  8. #8

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: clsBSTR - the ultimate string class

    No. It holds data it in an Integer array, but it also keeps a custom String variable holding the information for fast access when required. For example there are no conversions done when you get the current data of the class:
    Code:
    ' get string
    Public Property Get Value() As String
        Value = CharStr
    End Property
    A direct copypaste from the class.


    The string variable (CharStr) is "faked" to point to the data Integer array holds. In the other hand, the Integer array has some extra buffer in both sides of the data, thus making Append and Prepend much faster, so there is less need for constant space allocation when adding data. BufferAllocSize controls how much space is reserved on both sides of the data when allocation must done.
    Last edited by Merri; Jun 9th, 2007 at 11:41 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width