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 3 years have passed since last update.

【ExcelVBA】文字列結合の速度比較

Posted at

はじめに

以前に【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を使うのも良さそう。

参考URL

0
0
2

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?