Page 2 of 2 FirstFirst 12
Results 41 to 63 of 63

Thread: String Optimization

  1. #41
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: String Optimization

    I agree with leinad in this one. I originally went on ahead with the offtopic since there wasn't anything better to get on with (and besides, it did get some nice information out). Looking at just one point and finding "The Best" solution for that isn't enough, you still have to look at the bigger picture. And even that "Best Solution" doesn't work for everything (and I still value fixed size growth "better" for most cases). In this case the best one would be to not use ReDim Preserve in the first place, and it can be done easily. Thus talking about the best way to increase an array with ReDim Preserve is "obsolete" at this point and would be only worthy in it's own dedicated thread. Which we don't have.

    Hope we'll get a reply from the thread starter, the thread got longer than I expected very fast (and I didn't notice it until we were on the second page ). We can't help further with the optimization until we know more of what the arrays contain and what is being done.

  2. #42

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    thanks all i was trying to make a word wrap routine so that i can use it to send output to the printer. But i will still keep looking. any ideas?

  3. #43
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: String Optimization

    Quote Originally Posted by leinad31 View Post
    Of course it will have no relevance if you choose it interpret it as such. It was in reply to what was raised... I really couldn't care less who raised it.
    You doggedly refused to answer the question I raised, instead focusing solely on the OP's specific question. So clearly you did care who raised the question.

    I repeat: When you need to write a solution where you can't possibly know how many items your array will eventually need -- anywhere from hundreds to millions -- what is the best way to grow that array inside a loop?

  4. #44
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: String Optimization

    Quote Originally Posted by coolcurrent4u View Post
    thanks all i was trying to make a word wrap routine so that i can use it to send output to the printer. But i will still keep looking. any ideas?
    Didn't si's solution in post 3 and Merri's solution in post 4 both work?

  5. #45
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: String Optimization

    Quote Originally Posted by Ellis Dee View Post
    I repeat: When you need to write a solution where you can't possibly know how many items your array will eventually need -- anywhere from hundreds to millions -- what is the best way to grow that array inside a loop?
    Continuing in Array ReDim performance thread.

  6. #46

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    Quote Originally Posted by MartinLiss View Post
    What are you trying to do? An example in words would help.
    the routine is to filter an array of word eg

    original array ('aa','ab','ac','ad','ae','af','ag','ah','ai','aj')

    now remove the following array of words ('ah','af','aa','aj')


    this should produce

    ('ab','ac','ad','ae','ag','ai')

    hope it explains what am trying to do
    Last edited by coolcurrent4u; May 17th, 2009 at 05:51 AM.

  7. #47

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    th reason is to code a word wrapping routine and at the same time to filter an array of words

  8. #48
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: String Optimization

    Quote Originally Posted by coolcurrent4u View Post
    th reason is to code a word wrapping routine and at the same time to filter an array of words
    Sort both arrays first.

    Iterate through second array. If there are duplicates then skip if next element (if not at end of second array) is the same (no sense in searching for the same token in first array twice since first pass would have already removed it).

    Find start and end location (array index) of token in first array (to determine how many will be removed). Use Copy Memory API to shift trailing elements towards start index.

    For next token in second array, start looking in first array from where you left off (don't restart search at index 0, or you will need to keep track of index in first array).

    Repeat process until all tokens in second array have been processed.


    Variation is to process the arrays from the end rather than at index 0. This way you end up moving less array elements with copymemory in succeeding passes. There are already several samples in using CopyMemory, do a search.


    Summary of concepts:
    - Minimize redim preserve (for above process, just once)
    - Perform bulk copy instead of moving them one by one (use of CopyMemory).
    - You don't always have to process the data as it is. Sometimes it is better to transform data to facilitate processing (tokens sorted first, better if already sorted beforehand such as when array element was added).
    - Understand the context of the process... don't focus on just several lines of code (perform relevant systems analysis and design). You also have to take into consideration how components interact at run-time. Try to meet the system requirements as a whole rather than individually.
    Last edited by leinad31; May 21st, 2009 at 12:52 AM.

  9. #49
    Former Admin/Moderator MartinLiss's Avatar
    Join Date
    Sep 1999
    Location
    San Jose, CA
    Posts
    33,431

    Re: String Optimization

    Quote Originally Posted by coolcurrent4u View Post
    the routine is to filter an array of word eg

    original array ('aa','ab','ac','ad','ae','af','ag','ah','ai','aj')

    now remove the following array of words ('ah','af','aa','aj')


    this should produce

    ('ab','ac','ad','ae','ag','ai')

    hope it explains what am trying to do
    Can the original array contain duplicates, in other words something like this?

    original array ('aa','ab','ac','aa','ad','ae','af','ag','aa','ah','ai','aj')

  10. #50

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Question Re: String Optimization

    Quote Originally Posted by MartinLiss View Post
    Can the original array contain duplicates, in other words something like this?

    original array ('aa','ab','ac','aa','ad','ae','af','ag','aa','ah','ai','aj')
    yes it can contain duplicates. of course younever can know what data will be passed to the function or mabe class
    eg

    function filterwords(arry1,arry2)

    ......

    end function

  11. #51

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Question Re: String Optimization

    Quote Originally Posted by leinad31 View Post
    Sort both arrays first.

    Iterate through second array. If there are duplicates then skip if next element (if not at end of second array) is the same (no sense in searching for the same token in first array twice since first pass would have already removed it).

    Find start and end location (array index) of token in first array (to determine how many will be removed). Use Copy Memory API to shift trailing elements towards start index.

    For next token in second array, start looking in first array from where you left off (don't restart search at index 0, or you will need to keep track of index in first array).

    Repeat process until all tokens in second array have been processed.


    Variation is to process the arrays from the end rather than at index 0. This way you end up moving less array elements with copymemory in succeeding passes. There are already several samples in using CopyMemory, do a search.


    Summary of concepts:
    - Minimize redim preserve (for above process, just once)
    - Perform bulk copy instead of moving them one by one (use of CopyMemory).
    - You don't always have to process the data as it is. Sometimes it is better to transform data to facilitate processing (tokens sorted first, better if already sorted beforehand such as when array element was added).
    - Understand the context of the process... don't focus on just several lines of code (perform relevant systems analysis and design). You also have to take into consideration how components interact at run-time. Try to meet the system requirements as a whole rather than individually.
    can you please give me a working code

  12. #52
    Head Hunted anhn's Avatar
    Join Date
    Aug 2007
    Location
    Australia
    Posts
    3,669

    Re: String Optimization

    If both arrays are not too large, this is a simple way to filter as you want:
    Code:
    Sub FilterArray(Array1, Array2)
       Dim sTemp As String, sItem As String
       Dim i As Long
       
       If IsArray(Array1) = False Then Exit Sub
       If IsArray(Array2) = False Then Exit Sub
       
       sTemp = vbTab & Join(Array1, vbTab) & vbTab
       For i = LBound(Array2) To UBound(Array2)
          sItem = vbTab & Array2(i) & vbTab
          Do While InStr(sTemp, sItem)
             sTemp = Replace(sTemp, sItem, vbTab)
          Loop
       Next
       sTemp = Mid$(sTemp, 2, Len(sTemp) - 2)
       Array1 = Split(sTemp, vbTab)
    
    End Sub
    Code:
    Sub Test()
       Dim Array1, Array2
       Dim i As Long
       
       Array1 = Array("aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj")
       Array2 = Array("ah", "af", "aa", "aj")
       FilterArray Array1, Array2
       
       For i = 1 To UBound(Array1)
          Debug.Print Array1(i)
       Next
    End Sub
    • Don't forget to use [CODE]your code here[/CODE] when posting code
    • If your question was answered please use Thread Tools to mark your thread [RESOLVED]
    • Don't forget to RATE helpful posts

    • Baby Steps a guided tour
    • IsDigits() and IsNumber() functions • Wichmann-Hill Random() function • >> and << functions for VB • CopyFileByChunk

  13. #53
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: String Optimization

    BTW I assumed that the array is large and that data volume is one of the root causes of performance bottleneck (hence copymemory suggestion).

  14. #54
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: String Optimization

    There is also VB inbuilt mechanism:
    Code:
    Option Explicit
    
    Private Sub Form_Load()
        Dim strArray() As String, strRemove() As String, lngA As Long
        
        strArray = Split("aa ab ac ad ae af ag ah ai aj")
        strRemove = Split("ah af aa aj")
        
        For lngA = 0 To UBound(strRemove)
            strArray = Filter(strArray, strRemove(lngA), False)
        Next lngA
        
        For lngA = 0 To UBound(strArray)
            Debug.Print strArray(lngA)
        Next lngA
    End Sub
    Haven't tested the performance.


    Edit!
    Since I had some code ready I thought to post a slightly optimized version:
    Code:
    Option Explicit
    
    Private Sub Form_Load()
        Dim strArray() As String, strRemove() As String, lngA As Long
        Dim SF As New StringFilter
        
        strArray = Split("aa ab ac ad ae af ag ah ai aj")
        strRemove = Split("ah af aa aj")
        
        SF.Filter strArray, strRemove
        
        For lngA = 0 To UBound(strArray)
            Debug.Print strArray(lngA)
        Next lngA
    End Sub
    Of course the most interesting code is here: StringFilter.cls – the Filter procedure can be optimized further by sorting at least the Match array and then taking the return value of BinaryCompare/lstrcmpW/lstrcmpiW on comparison and ending comparisons if it is an exact match or if we already went through the possible matches.
    Last edited by Merri; May 22nd, 2009 at 08:21 AM. Reason: Variant arrays to String arrays

  15. #55

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    many thanks for all ya contributions

  16. #56
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: String Optimization

    Quote Originally Posted by coolcurrent4u View Post
    many thanks for all ya contributions
    OP, I am not sure why you are trying to choke off this thread. I find it fascinating. When AnHn threw his hat in the ring, things really got interesting. We have a discussion going on between 5 or 6 of the best programmers that exist. That's MHO.

    Can someone write a PM to Logophobic to alert him of this thread? I think it deserves his input on growing an array.
    Doctor Ed

  17. #57

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Exclamation Re: String Optimization

    ok, i just thot abt somting, if i actually have a string of words and will like to remove duplicate words from the string. so i thot converting the string to array andthen filtering it.

    but i ound that this is slower as in an instance one array could be 1 million words long convertingto array and then convertingback to string is dam slow

    what do you guys suggest?


    thanks in advance for any help

  18. #58

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    Code Doc i dont understand what you are trying to say?

    We have a discussion going on between 5 or 6 of the best programmers that exist. That's MHO

  19. #59

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    can the vb Filter function be used here?

  20. #60
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: String Optimization

    VB's Filter would be too slow, it creates a new array each time it is called. A better method in your case would be so separate the words into a sorted string array and then remove the duplicates.

    You can see a somewhat better approach in StringSort.cls and it's FilterDuplicates method. It isn't optimal, but it uses Merge Sort to create a sorted index array, then remove duplicates and finally sort the indexes back into their original order and create a new array. It for the least beats the easiest-to-come-up-with functions by a great margin (easy: 1) add to Collection using Key or 2) compare each string array item against each other).

    There was another thread on almost the same subject, but I'm too lazy to search for it atm

  21. #61
    Head Hunted anhn's Avatar
    Join Date
    Aug 2007
    Location
    Australia
    Posts
    3,669

    Re: String Optimization

    Quote Originally Posted by coolcurrent4u View Post
    Code Doc i dont understand what you are trying to say?
    We have a discussion going on between 5 or 6 of the best programmers that exist. That's MHO
    Code Doc is one of them, I am not.

    I have spent 3 hours on another approach that is much faster as below. Code Doc and others are welcome to optimize it.
    This only works with ANSI text file.
    The test was run on WIN32API.TXT with filesize of 652KB that contains 86,445 words. After filtered it was reduced to 9,634 words.
    The data reading from the text file is converted to lowercase and cleaned up to remove all non-English-alphabet characters.
    All words are separated by single-spaces.
    26 Dic strings are used to stored non-duplicated words found.
    Code:
    Option Explicit
    
    Sub FilterDuplicateWords()
        Dim sFolder As String, sFName As String
        Dim bData() As Byte, bData2() As Byte
        Dim sData As String, sWord As String
        Dim sDic(0 To 25) As String
        Dim m(0 To 25) As Long
        Dim bSpace As Byte, b As Byte
        Dim i As Long, j As Long, n As Long, p As Long
        Dim w(-1 To 26) As Long
        
        Dim sMsg As String
        Dim t As Single
            
        t = Timer
            
        sFolder = "C:\API\"
        sFName = "WIN32API.TXT"
        
        Open sFolder & sFName For Binary As #1
        sData = Input(LOF(1), 1)
        Close #1
        
        sMsg = "Reading Data: " & vbTab & (Timer - t) & " seconds"
        t = Timer
        
        bData = StrConv(LCase(sData), vbFromUnicode)
        
        sMsg = sMsg & vbCrLf & "Converting: " & vbTab & (Timer - t) & " seconds"
        t = Timer
        
        '-- clean up Data --------------------------------
        ReDim bData2(UBound(bData) + 2)
        bData2(0) = 32 '-- set a Space as first chararcter
        bSpace = 1
        j = 0
        For i = 0 To UBound(bData)
            Select Case bData(i)
                Case 97 To 122:  j = j + 1: bData2(j) = bData(i): bSpace = 0
                Case Else: If bSpace Then Else j = j + 1: bData2(j) = 32: bSpace = 1
            End Select
        Next
        If bSpace Then Else j = j + 1: bData2(j) = 32 '-- set a Space as last chararcter
        ReDim Preserve bData2(j)
        
        sData = StrConv(bData2, vbUnicode)
        Erase bData, bData2
        
        sMsg = sMsg & vbCrLf & "Cleaning up: " & vbTab & (Timer - t) & " seconds"
        t = Timer
    
        '-- Filering duplicate words ----------------------
        For b = 0 To 25
            sDic(b) = Space$(Len(sData))        '-- prepare rooms for Dic
            m(b) = 1                            '-- first space position in Dic(b)
        Next
        i = 1 '-- first space position in data
        p = 1 '-- last space position in new data
        Do While i < Len(sData)
            j = InStr(i + 1, sData, " ")        '-- next space position in data
            n = j - i + 1                       '-- len of word with leading and trailing spaces
            sWord = Mid$(sData, i, n)           '-- next word found in data
            b = Asc(Mid$(sWord, 2, 1)) - 97     '-- index of Dic
            w(-1) = w(-1) + 1                   '-- original word counter
            If InStrB(1, Left$(sDic(b), m(b)), sWord) = 0 Then '-- search Dic(b)
                Mid$(sDic(b), m(b), n) = sWord  '-- word not found, add to Dic
                m(b) = m(b) + n - 1             '-- last space position in Dic(b)
                w(b) = w(b) + 1                 '-- Dic(b) word counter
                Mid$(sData, p, n) = sWord       '-- also add word to new data to pretend order
                p = p + n - 1                   '-- last space position in new data
                w(26) = w(26) + 1               '-- new word counter
            End If
            i = j
        Loop
        
        sMsg = sMsg & vbCrLf & "Filtering:   " & vbTab & (Timer - t) & " seconds"
        t = Timer
        
        '-- Saving filtered words ------------------
        Open sFolder & "Words.txt" For Output As #1
        Print #1, Mid$(sData, 1, p);
        Close #1
            
        sMsg = sMsg & vbCrLf & "Saving Data: " & vbTab & (Timer - t) & " seconds"
        
        sMsg = sMsg & vbCrLf & vbCrLf & "Before Filtered: " & vbTab & w(-1) & " words"
        sMsg = sMsg & vbCrLf & "After Filtered: " & vbTab & w(26) & " words"
        For b = 0 To 25
            sMsg = sMsg & vbCrLf & Chr$(b + 97) & " = " & w(b)
        Next
        
        MsgBox sMsg
        
        sData = "": Erase sDic, m, w
    
    End Sub
    Code:
    Reading Data:   2.15625 seconds
    Converting:     0.015625 seconds
    Cleaning up:    0.265625 seconds
    Filtering:      1.078125 seconds
    Saving Data:    0.015625 seconds
    
    Before Filtered:    86445 words
    After Filtered:     9634 words
    a = 386
    b = 308
    c = 774
    d = 835
    e = 446
    f = 363
    g = 588
    h = 324
    i = 489
    j = 40
    k = 39
    l = 860
    m = 465
    n = 472
    o = 244
    p = 579
    q = 50
    r = 438
    s = 983
    t = 258
    u = 189
    v = 82
    w = 357
    x = 35
    y = 21
    z = 9
    • Don't forget to use [CODE]your code here[/CODE] when posting code
    • If your question was answered please use Thread Tools to mark your thread [RESOLVED]
    • Don't forget to RATE helpful posts

    • Baby Steps a guided tour
    • IsDigits() and IsNumber() functions • Wichmann-Hill Random() function • >> and << functions for VB • CopyFileByChunk

  22. #62

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    anhn

    just how do i use your code example. which is the large array and which is the smallar array

    the large array is assumed to be the one containig long words
    the small array the the words that will either be removed or kept in th larger array
    thanks

  23. #63

    Thread Starter
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: String Optimization

    Can you help me otimize this code, i found a way my sefl but it has some bugs
    vb Code:
    1. Function ExtractWords(WordsToFind() As String, FindInText() As String, Optional Keep As Boolean = True) As String()
    2.     Dim tmpArray()      As String
    3.     Dim i               As Long, intT1 As Long, intT2 As Long, j As Long, k As Long
    4.     '// check for empty variables//
    5.     If UBound(WordsToFind) = -1 Or UBound(FindInText) = -1 Then
    6.         Exit Function
    7.     End If
    8.     '// check if we have multiple words //
    9.     intT1 = UBound(WordsToFind)
    10.     intT2 = UBound(FindInText)
    11.     k = -1
    12.     For i = 0 To intT2 - 1
    13.         For j = 0 To intT1
    14.             If Keep = True Then
    15.                 If InStr(1, FindInText(i), WordsToFind(j), vbTextCompare) > 0 Then
    16.                     k = k + 1
    17.                     ReDim Preserve tmpArray(k)
    18.                     If Not inArray(FindInText(i), tmpArray()) Then
    19.                         tmpArray(k) = Trim$(FindInText(i))
    20.                     End If
    21.                 End If
    22.        
    23.             Else
    24.                 If InStr(1, FindInText(i), WordsToFind(j), vbTextCompare) < 1 Then
    25.                     k = k + 1
    26.                     ReDim Preserve tmpArray(k)
    27.                     If Not inArray(FindInText(i), tmpArray()) Then
    28.                         tmpArray(k) = Trim$(FindInText(i))
    29.                     End If
    30.                 End If
    31.             End If
    32.         Next
    33.     Next
    34.     ExtractWords = tmpArray
    35. End Function
    36. Function inArray(SearchText As String, StringArray() As String) As Boolean
    37.     Dim tmpStrings()      As String, tmpString As String
    38.     tmpString = Join(StringArray, " ")
    39.     tmpStrings() = Split(tmpString, SearchText)
    40.     If UBound(tmpStrings()) > 0 Then
    41.         inArray = True
    42.     Else
    43.         inArray = False
    44.     End If
    45. End Function

Page 2 of 2 FirstFirst 12

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