0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VBAにおける正規表現の性能評価1

Posted at

結論

VBAの正規表現では、正規表現オブジェクトの生成にかなりコストがかかっているのでできるだけ使い回すか、通常のテキスト処理で代用しましょう。

実験結果

  1. 正規表現オブジェクトを毎回生成
  • 10万件:34秒
  1. 正規表現オブジェクトを使い回す
  • 100万件:6秒
  1. InstrとRightでテキスト処理
  • 1000万件:7秒

実行コード

ある文字列から、★が現れるまでを抽出

実行環境

  • Windows 7
  • Excel 2010
  • Microsoft Visual Basic for Applications 7.1
  • i5 M460 2.53GHz

1. 正規表現オブジェクトを毎回生成

10万件:34秒

sample
Sub sample()
    Dim output As String
    Dim StartTime, StopTime As Variant
    
    StartTime = Time
    
    For i = 1 To 10000
        output = sampleRegEx("犯人はこのなかにいる★ぞ!!!") & vbNewLine
    Next i

    StopTime = Time
    StopTime = StopTime - StartTime

    MsgBox "ケース1:所要時間は" & Minute(StopTime) & "分" & Second(StopTime) & "秒 でした"

End Sub


'' 引数に★があるとき、先頭から★のひとつまえまでの文字を切り出して返却する
Private Function sampleRegEx(ByVal message As String)
    Dim RE As Object, Matches  As Object
    
    Set RE = CreateObject("VBScript.RegExp")
    
    '' 正規表現を用いて、「)」が文末にのみ存在する最初のシートを抽出する(例:発注覚書2015-02-18(水))。
    strPattern = "^([^★]+)"
    With RE
        .Pattern = strPattern       ''検索パターンを設定
        .IgnoreCase = True          ''大文字と小文字を区別しない
        .Global = True              ''文字列全体を検索
    End With
    
    Set Matches = RE.Execute(message)
    
    sampleRegEx = Matches.Item(0).Value
   
    Set RE = Nothing
End Function

2.正規表現オブジェクトを使い回す

100万件:6秒

sample2
'' 引数に★があるとき、先頭から★のひとつまえまでの文字を切り出して返却する
Sub sampleRegExZ()
    Dim RE As Object, Matches As Object
    Dim StartTime, StopTime As Variant
    Dim sampleRegEx As String
    
    Set RE = CreateObject("VBScript.RegExp")
    
    '' 正規表現を用いて、「)」が文末にのみ存在する最初のシートを抽出する(例:発注覚書2015-02-18(水))。
    strPattern = "^([^★]+)"
    With RE
        .Pattern = strPattern       ''検索パターンを設定
        .IgnoreCase = True          ''大文字と小文字を区別しない
        .Global = True              ''文字列全体を検索
    End With
    
    StartTime = Time
    For i = 1 To 10000000
       message = "犯人はこのなかにいる★ぞ!!!"
       Set Matches = RE.Execute(message)
       sampleRegEx = Matches.Item(0).Value
    Next i
    StopTime = Time
    StopTime = StopTime - StartTime
    MsgBox "ケース2:所要時間は" & Minute(StopTime) & "分" & Second(StopTime) & "秒 でした"
   
    Set RE = Nothing
End Sub

3. InstrとRightでテキスト処理

1000万件:7秒

sample3
Sub sample3()
    Dim output As String
    Dim StartTime, StopTime As Variant
    
    StartTime = Time
    StartTime = Time
    For i = 1 To 10000000
        output = sampleInstr("犯人はこのなかにいる★ぞ!!!") & vbNewLine
    Next i

    StopTime = Time
    StopTime = StopTime - StartTime

    MsgBox "ケース3:所要時間は" & Minute(StopTime) & "分" & Second(StopTime) & "秒 でした"
End Sub


'' 引数に★があるとき、先頭から★のひとつまえまでの文字を切り出して返却する
Private Function sampleInstr(ByVal message As String)
    Dim pos As Integer
    
    pos = InStr(message, "★")
    If pos > 0 Then
        sampleInstr = Right(message, pos)
    Else
        sampleInstr = message
    End If
End Function

雑感

  • Qiitaでこれくらいの調べればすぐわかるの書くのは文化的にどうなんでしょうか
  • VBAでライブラリっぽいのどういう文化なんだろう。どう探せばよいのやら・・
  • VBAの性能がどこで左右されているかもっと細かいところ調べるにはどうしたらいいか調べなきゃ
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?