はじめに
以前に【ExcelVBA】文字列操作用のユーティリティ関数を自作してみたという記事を書きましたが、この記事では文字列から空白を除去したり、文字列中に部分文字列が含まれるかを調べたりする処理をまとめたもので、文字列結合については全く触れていませんでした。
そこで2年ほど前に書いた【Java】文字列結合の速度比較という記事と同様に、文字列を単純に結合させる場合と、少し工夫した場合とで速度比較をしてみました。
テスト環境
- PC
- CPU:Ryzen7 3700X
- RAM:32GB
- SSD:Samsung SSD 970 EVO Plus 500GB
- Excel:Excel 2013 (32bit)
テストに使用したコード
- "abc"という文字を10万回結合するコードを作成しました。
- 以下の3種類のコードで速度比較をしてみました。
- 「&」を用いた単純な文字列結合
- 固定長の配列+Join関数を用いた文字列結合
- 動的配列+Join関数を用いた文字列結合
- こちらの記事ではMid関数を使った高速化の方法も紹介されていましたが、今回は割愛しました。
StringConcat.bas
Option Explicit
'------------------------------------------------------------------------------
' 文字列結合の速度比較
'------------------------------------------------------------------------------
' 結合させる文字列
Private Const SAMPLE_TXT As String = "abc"
' メイン処理
Sub main()
Call SimpleConcat
Call ArrayJoin
Call DynamicArrayJoin
End Sub
' 単純な文字列結合
Sub SimpleConcat()
Dim startTime As Double, endTime As Double, processTime As Double
startTime = Timer
Dim i As Long
Dim buff As String
For i = 0 To (100000 - 1)
buff = buff & SAMPLE_TXT
Next i
endTime = Timer
processTime = endTime - startTime
Debug.Print "SimpleConcatの処理時間:" & processTime
End Sub
' 固定長の配列を使った文字列結合
Sub ArrayJoin()
Dim startTime As Double, endTime As Double, processTime As Double
startTime = Timer
Dim i As Long
Dim buff As String
Dim ary(99999) As String
For i = 0 To (100000 - 1)
ary(i) = SAMPLE_TXT
Next i
buff = Join(ary, "")
endTime = Timer
processTime = endTime - startTime
Debug.Print "ArrayJoinの処理時間:" & processTime
End Sub
' 動的配列を使った文字列結合
Sub DynamicArrayJoin()
Dim startTime As Double, endTime As Double, processTime As Double
startTime = Timer
Dim i As Long
Dim buff As String
Dim ary() As String
For i = 0 To (100000 - 1)
ReDim Preserve ary(i)
ary(i) = SAMPLE_TXT
Next i
buff = Join(ary, "")
endTime = Timer
processTime = endTime - startTime
Debug.Print "ArrayJoinの処理時間:" & processTime
End Sub
テスト結果
テスト結果
SimpleConcatの処理時間:2.265625
ArrayJoinの処理時間:0.015625
ArrayJoinの処理時間:0.015625
テスト結果の考察
- 予想通り、単純な文字列結合が2秒以上と最も遅かったです。
- 固定長の配列を使った方法が最も速いかと思いましたが、意外にも動的配列を使った方法と同じ処理時間でした。
- テスト後に気になって調べてみたところ、こちらの記事では「(配列の要素数を徐々に拡張するよりも)Redimで事前に要素数を確保しておく方が速い」と書かれていましたが、私の環境ではいずれも変わらない結果でした。
-
Redim Preserve...
による配列の要素数変更は、高スペックなPCだと無視できるほどコストが小さい処理なのかもしれません。 - あるいはExcelのバージョンによって動作速度が異なっている可能性もありますが、現時点でははっきりとした理由が分かりません。
まとめ
- ちょっとした文字列結合なら「&」でも問題なさそう。
- 文字列を連結させてCSVやHTMLなど大きなテキストデータを生成する際に、処理時間を少しでも短くしたいのであれば、配列(もしくは動的配列)+JOINを使うのも良さそう。