Results 1 to 8 of 8

Thread: LIKE Operator speed-up without additional references

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2009
    Location
    Germany
    Posts
    47

    LIKE Operator speed-up without additional references

    Hello all,

    is there any faster way to compare multiple strings via regex-patterns than I did in the example code below?
    This code works very well, but becomes slow when executed multiple times in a for-loop
    (tested with QueryPerformanceCounter-/QueryPerformanceFrequency-API).
    Please note that my intention is to avoid additional references to runtime libraries
    (e.g. Microsoft Scripting Runtime) and/or API-declarations as much as possible.

    Do I have to rely on this code or are there any speed improvements around despite the selfimposed limitations above?

    Any suggestion is greatly appreciated.


    Zphere


    Example bas-module:
    Code:
    Option Explicit
    Private Const REGEX_PATTERN1 As String = "REGEX1|REGEX2|REGEX3"
    Private Const REGEX_PATTERN2 As String = "REGEX4|REGEX5|REGEX6|REGEX7|REGEX8|REGEX9|REGEX10|REGEX11|REGEX12"
    Private Const REGEX_PATTERN3 As String = "REGEX13|REGEX2|REGEX14"
    
    Public Function LikeEx(ByRef vValue As Variant, sArg As String, Optional Delim As String = "|") As Boolean
    ' Like-Operator - supports multiple arguments by delimiter (pipe as default)
      Dim X As Long, sArr() As String
      sArr = Split(sArg, Delim)
      For X = LBound(sArr) To UBound(sArr)
        If sArr(X) <> vbNullstring Then
          If vValue Like sArr(X) Then LikeEx = True: Exit For ' artificial OR
        End If
      Next
      Erase sArr
    End Function
    
    Private Sub Test(ArrIn() as variant)
      For I = LBound(ArrIN, 2) To UBound(ArrIN, 2)  
        Select Case True
    
          Case LikeEx(ArrIn(0,I, REGEX_PATTERN1)
               LikeEx(ArrIn(0,I, REGEX_PATTERN2)
               Do something
    
          Case LikeEx(ArrIn(0,I, REGEX_PATTERN2)
               LikeEx(ArrIn(0,I, REGEX_PATTERN3)
               Do something
    
          Case LikeEx...
          Case LikeEx...
          Case LikeEx...
        End Select
      Next
    End Sub
    Edit: changed sNULL to vbNullstring
    Last edited by Zphere; Aug 6th, 2021 at 11:50 AM.

  2. #2
    PowerPoster
    Join Date
    Nov 2017
    Posts
    3,116

    Re: LIKE Operator speed-up without additional references

    This could be a terrible idea, I don't have the time to test this out, but one thought is this:

    In your LikeEx function, instead of splitting the string by the delimiter and then trying to match an element one by one, why not just do an Instr against sArg looking for:

    Code:
    Delim & vValue & Delim
    If it finds an inside match, return true, otherwise return false.

    Of course, the first value won't have a leading Delim, and the last value won't have a trailing Delim, so you would need to handle that in order for the first or last values to be found.

  3. #3

    Thread Starter
    Member
    Join Date
    Dec 2009
    Location
    Germany
    Posts
    47

    Re: LIKE Operator speed-up without additional references

    Thanks OptionBase1,

    I cannot use Instr because it's not able to handle regex patterns as the like operator.
    I've to compare a specific array value against regular expression patterns from the array items.
    Predefined constant values contain strings like this (example):
    "substr1[#]substr2[#]*|substr3#*|substr4{?*?}*|"[a-z]:|substr5#*substr6#*|substr7|substr8".

    Sorry, maybe I should have been a little more specific.
    Last edited by Zphere; Aug 6th, 2021 at 12:46 PM.

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: LIKE Operator speed-up without additional references

    I found one possible contender: PathMatchSpecExW

    However it has a number of limitations: always case-insensitive, limited to file-matching wildcards.

    It is also slightly slower than Like used with Option Compare Text, and much slower without it (case-sensitive Like beats it by a mile).

    So its only compelling use might be when you want to do file path pattern matches 100% compatibly with those in Windows operations.

  5. #5

    Thread Starter
    Member
    Join Date
    Dec 2009
    Location
    Germany
    Posts
    47

    Re: LIKE Operator speed-up without additional references

    Nice find, thank you very much dilettante,

    I visited this ms-site so often but never recognised this api as interesting in the left scroll-down menu.
    However, according to your test results (I assume you did) it doesn't seem to be a real alternative to Like.?
    Although case-insensitivity is exactly what I need, array items to compare against are not filenames or file paths.

    Anyway, thanks a lot

    Zphere
    Last edited by Zphere; Aug 6th, 2021 at 01:14 PM.

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: LIKE Operator speed-up without additional references

    I also found: SymMatchStringW

    This can be case sensitive or not, but it also only handles * and ? wildcard symbols and is no faster than the other call in its case-insensitive mode.
    Last edited by dilettante; Aug 6th, 2021 at 01:17 PM.

  7. #7
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: LIKE Operator speed-up without additional references

    Defining them in a typelib might raise performance a hair, but probably still not close to Like and you still have the wildcard symbol limitations.

  8. #8

    Thread Starter
    Member
    Join Date
    Dec 2009
    Location
    Germany
    Posts
    47

    Re: LIKE Operator speed-up without additional references

    Okay,

    most important for me is a search against pattern ranges ("[]") also.
    Reading the information from the provided link, this is not explicitly stated by MS.

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