Results 1 to 7 of 7

Thread: Need help optimizing URLEncode, or rewriting it

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2002
    Posts
    229

    Need help optimizing URLEncode, or rewriting it

    Hey, check out the following function. I did some testing on it and I think it could be a little faster. Now I don't know what else I can do to make it faster. I tried replacing the StrConv function to CopyMemoryStringToAny, and that did VERY LITTLE difference on a 100000 loop (like 100 ms at the most). Is there a better way to do it all together?

    VB Code:
    1. Public Function UrlEncode(ByVal urlText As String) As String
    2.     Dim ANSI() As Byte
    3.     Dim ASCII As Long
    4.     Dim encText As String
    5.     Dim I As Long
    6.    
    7.     On Error GoTo UrlEncode_Error
    8.    
    9.     ANSI = StrConv(urlText, vbFromUnicode)
    10.    
    11.     For I = 0 To UBound(ANSI)
    12.         ASCII = (ANSI(I) + 2) Mod 256   'Roll over back to 0 past 255, else HEX and CHR won't work
    13.        
    14.         Select Case ASCII
    15.             Case 48 To 57, 65 To 90, 97 To 122  'Letters and Numbers
    16.                 encText = encText & Chr(ASCII)
    17.                
    18.             Case 32     'Spaces
    19.                 encText = encText & "+"
    20.                
    21.             Case 0 To 16    'Low Hex characters
    22.                 encText = encText & "%0" & Hex(ASCII)
    23.                
    24.             Case Else   'Special Characters
    25.                 encText = encText & "%" & Hex(ASCII)
    26.         End Select
    27.     Next I
    28.      
    29.     UrlEncode = encText
    30.    
    31.     Exit Function
    32.  
    33. UrlEncode_Error:
    34.     MsgBox "Error #:" & Err.Number & vbCrLf & "Procedure [UrlEncode] of Module [mNetFunctions]" & vbCrLf & "Description: " & Err.Description, vbOKOnly, "Error Handling"
    35. End Function

  2. #2
    Hyperactive Member
    Join Date
    Jun 2006
    Posts
    372

    Re: Need help optimizing URLEncode, or rewriting it

    have you seen:
    http://vbnet.mvps.org/index.html?cod...apicompare.htm
    then navigate to code library, internet, look for article called :


    UrlCanonicalize: Proper URL Path Encoding and Decoding

  3. #3
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Need help optimizing URLEncode, or rewriting it

    I don't know why your adding 2 on this line: ASCII = (ANSI(I) + 2) Mod 256, but assuming that you need to do that for some reason I would use the following code since the big bulk is the string concatenation (my changes is shown in bold).
    VB Code:
    1. Public Function UrlEncode(ByVal urlText As String) As String
    2.     Dim ANSI() As Byte
    3.     Dim ASCII As Long
    4.     Dim encText As String
    5.     Dim I As Long
    6. [b]    Dim nPos As Long [/b]
    7.     On Error GoTo UrlEncode_Error
    8.  
    9. [b]    encText = Space$(Len(urlText) * 3) 'create a buffer big enough for the result
    10.     nPos = 1[/b]
    11.     ANSI = StrConv(urlText, vbFromUnicode)
    12.    
    13.     For I = 0 To UBound(ANSI)
    14.         ASCII = (ANSI(I) + 2) Mod 256   'Roll over back to 0 past 255, else HEX and CHR won't work
    15.        
    16.         Select Case ASCII
    17.             Case 48 To 57, 65 To 90, 97 To 122  'Letters and Numbers
    18. [b]                Mid(encText, nPos) = Chr(ASCII)
    19.                 nPos = nPos + 1 [/b]
    20.             Case 32     'Spaces
    21. [b]                Mid(encText, nPos) = "+"
    22.                 nPos = nPos + 1 [/b]
    23.             Case 0 To [b]15[/b]    'Low Hex characters [b](16 is 10 in hex)[/b]
    24. [b]                Mid(encText, nPos) = "%0"
    25.                 Mid(encText, nPos + 2) = Hex(ASCII)
    26.                 nPos = nPos + 3 [/b]
    27.             Case Else   'Special Characters
    28. [b]                Mid(encText, nPos) = "%"
    29.                 Mid(encText, nPos + 1) = Hex(ASCII)
    30.                 nPos = nPos + 3 [/b]
    31.         End Select
    32.     Next I
    33.      
    34.     UrlEncode =[b] Left$(encText, nPos - 1)[/b]
    35.     Exit Function
    36.  
    37. UrlEncode_Error:
    38.     MsgBox "Error #:" & Err.Number & vbCrLf & "Procedure [UrlEncode] of Module [mNetFunctions]" & vbCrLf & "Description: " & Err.Description, vbOKOnly, "Error Handling"
    39. End Function
    The above should run a lot quicker.

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Mar 2002
    Posts
    229

    Re: Need help optimizing URLEncode, or rewriting it

    Awesome, thx, i'll test it out and respost my timing results. I never even knew that mid could be assigned a value! LOL i'm a nooob once again!

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

    Re: Need help optimizing URLEncode, or rewriting it

    You can also always get entirely rid of the slow string processing routines, such as Mid$:
    VB Code:
    1. Public Function URLencode_Merri(ByRef URL As String) As String
    2.     Static barOut() As Byte, barURL() As Byte
    3.     Dim lngA As Long, bytChar As Byte, bytNew As Byte, lngPos As Long
    4.     ' check length
    5.     If LenB(URL) = 0 Then Exit Function
    6.     ' convert input string to byte array
    7.     barURL = URL
    8.     ' reserve space for output string
    9.     ReDim Preserve barOut(LenB(URL) * 3 - 1)
    10.     ' happily loop ever after
    11.     For lngA = 0 To UBound(barURL) Step 2
    12.         ' minimal optimization trick
    13.         bytChar = barURL(lngA)
    14.         ' check what we have here
    15.         Select Case bytChar
    16.             ' numbers and letters
    17.             Case 48 To 57, 65 To 90, 97 To 122
    18.                 barOut(lngPos) = bytChar
    19.                 lngPos = lngPos + 2
    20.             ' space
    21.             Case 32
    22.                 barOut(lngPos) = 43 ' "+"
    23.                 lngPos = lngPos + 2
    24.             ' anything else
    25.             Case Else
    26.                 barOut(lngPos) = 37 ' "%"
    27.                 ' four upper bits
    28.                 bytNew = ((bytChar And &HF0) \ &H10) Or 48
    29.                 If bytNew < 58 Then
    30.                     barOut(lngPos + 2) = bytNew
    31.                 Else
    32.                     barOut(lngPos + 2) = bytNew + 7
    33.                 End If
    34.                 ' four lower bits
    35.                 bytNew = (bytChar And &HF) Or 48
    36.                 If bytNew < 58 Then
    37.                     barOut(lngPos + 4) = bytNew
    38.                 Else
    39.                     barOut(lngPos + 4) = bytNew + 7
    40.                 End If
    41.                 ' next starting position
    42.                 lngPos = lngPos + 6
    43.         End Select
    44.     Next lngA
    45.     ' error check
    46.     If lngPos = 0 Then Exit Function
    47.     ' resize output
    48.     ReDim Preserve barOut(lngPos - 1)
    49.     ' convert output to a string
    50.     URLencode_Merri = CStr(barOut)
    51. End Function

    Compile and you're closer to programmer's heaven. Closer, but not there.



    If you still need more...
    VB Code:
    1. Option Explicit
    2.  
    3. Dim URLencode_table(255) As Byte
    4. Dim HexTableUpper(255) As Byte
    5. Dim HexTableLower(255) As Byte
    6.  
    7. Public Sub Init_URLencode_table()
    8.     Dim bytNew As Byte, lngA As Long
    9.     For lngA = 0 To 255
    10.         Select Case lngA
    11.             Case 48 To 57, 65 To 90, 97 To 122
    12.                 URLencode_table(lngA) = CByte(lngA)
    13.             Case 32
    14.                 URLencode_table(lngA) = 43
    15.             Case Else
    16.                 URLencode_table(lngA) = 37
    17.         End Select
    18.        
    19.         bytNew = ((lngA And &HF0) \ &H10) Or 48
    20.         If bytNew < 58 Then
    21.             HexTableUpper(lngA) = bytNew
    22.         Else
    23.             HexTableUpper(lngA) = bytNew + 7
    24.         End If
    25.        
    26.         bytNew = (lngA And &HF) Or 48
    27.         If bytNew < 58 Then
    28.             HexTableLower(lngA) = bytNew
    29.         Else
    30.             HexTableLower(lngA) = bytNew + 7
    31.         End If
    32.     Next lngA
    33. End Sub
    34. Public Function URLencode_Merri(ByRef URL As String) As String
    35.     Static barOut() As Byte, barURL() As Byte
    36.     Dim lngA As Long, bytChar As Byte, lngPos As Long
    37.     ' init the table we need
    38.     If URLencode_table(0) = 0 Then Init_URLencode_table
    39.     ' check length
    40.     If LenB(URL) = 0 Then Exit Function
    41.     ' convert input string to byte array
    42.     barURL = URL
    43.     ' reserve space for output string
    44.     ReDim Preserve barOut(LenB(URL) * 3 - 1)
    45.     ' happily loop ever after
    46.     For lngA = 0 To UBound(barURL) Step 2
    47.         bytChar = URLencode_table(barURL(lngA))
    48.         barOut(lngPos) = bytChar
    49.         If bytChar <> 37 Then
    50.             lngPos = lngPos + 2
    51.         Else
    52.             barOut(lngPos + 2) = HexTableUpper(barURL(lngA))
    53.             barOut(lngPos + 4) = HexTableLower(barURL(lngA))
    54.             lngPos = lngPos + 6
    55.         End If
    56.     Next lngA
    57.     ' error check
    58.     If lngPos = 0 Then Exit Function
    59.     ' resize output
    60.     ReDim Preserve barOut(lngPos - 1)
    61.     ' convert output to a string
    62.     URLencode_Merri = CStr(barOut)
    63. End Function

    Minimizing all calculations within the loop.
    Last edited by Merri; Jul 11th, 2006 at 03:35 PM.

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Mar 2002
    Posts
    229

    Re: Need help optimizing URLEncode, or rewriting it

    Wow, truely amazing code by both of you guys. Ranked by speed, Merri's was slightly faster for 10000 executions by 70 ms (at 430 ms on my CPU), and joacim's ran at 500ms on my cpu, and mine runs at 640. so basically i cut down 200 ms for 10000 records. I don't think I'll be processing that much, but evey bit helps. thanks to both of you!

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

    Re: Need help optimizing URLEncode, or rewriting it

    I assume you didn't try it compiled with all advanced optimizations turned on, because on my computer it handled 10000 urls in 30 ms when I did that

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