結論
VBAの正規表現では、正規表現オブジェクトの生成にかなりコストがかかっているのでできるだけ使い回すか、通常のテキスト処理で代用しましょう。
実験結果
- 正規表現オブジェクトを毎回生成
- 10万件:34秒
- 正規表現オブジェクトを使い回す
- 100万件:6秒
- 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の性能がどこで左右されているかもっと細かいところ調べるにはどうしたらいいか調べなきゃ