【テクニカル・上級編】【高速データ処理】Scripting.Dictionary を活用した重複データの高速抽出と連想配列集計 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを再定義する:Scripting.Dictionaryによる「O(n)」の高速データ処理術

レガシーシステムの保守や、RPAが介在する自動化の現場において、未だVBScriptは現役だ。しかし、多くのエンジニアが「VBScriptは遅い」という先入観のもと、二重ループでデータを突き合わせるような非効率極まりないコードを量産している。

いいか、VBScriptの真髄は「COMオブジェクトをいかにメモリ上で効率的にハンドリングするか」にある。今回は、数万件規模のログ解析を一瞬で完結させる『Scripting.Dictionary』を用いたO(n)アルゴリズムの真髄を伝授する。

1. なぜ「Dictionary」が最強の武器なのか

配列を二重ループ(`For`の中に`For`)で回せば、計算量はO(n²)となる。データが1万件あれば、最大1億回の比較が発生する。これが「VBScriptは遅い」と言われる最大の原因だ。

`Scripting.Dictionary`は、内部的にハッシュテーブルを実装している。キーによるアクセスは理論上O(1)だ。つまり、データ件数が線形に増えても、処理時間は正比例でしか増えない。この差は、システム稼働時間において致命的な差を生む。

2. 高速重複排除の実装コード

以下のコードは、数万行のログファイルから「ユニークなユーザーID」を抽出し、それぞれの発生回数を集計する例だ。

‘ 高速データ集計エンジンの核心
Function AggregateLogData(arrData)
Dim dict, item, key
‘ Late Bindingでインスタンス化(パフォーマンスを考慮し適宜Early Bindingも検討)
Set dict = CreateObject(“Scripting.Dictionary”)

‘ メモリ最適化: CompareModeを設定し、大文字小文字を区別(vbBinaryCompare)または無視(vbTextCompare)
‘ デフォルトはバイナリ比較。仕様に合わせて明示的に設定せよ
dict.CompareMode = 1

‘ O(n)のループ処理: ここがボトルネック解消の鍵
For Each item In arrData
If Not dict.Exists(item) Then
dict.Add item, 1
Else
dict(item) = dict(item) + 1
End If
Next

Set AggregateLogData = dict
End Function

3. シニアエンジニアが意識すべき「メモリの流儀」

VBScriptはガベージコレクションを備えていない。COMオブジェクトのライフサイクル管理を疎かにすることは、メモリリークという名の「時限爆弾」を仕掛けることと同義だ。

オブジェクトの明示的解放(Destruction)

`Set dict = Nothing` を忘れるな。特に、WSHで長時間常駐するバックグラウンドプロセスにおいては、スコープを抜ける前に必ず参照を断ち切る必要がある。

Sub ProcessMaster()
Dim oDict
Set oDict = AggregateLogData(sourceArray)

‘ 処理実行…

‘ スコープ終了直前に明示的解放
Set oDict = Nothing
End Sub

4. 極限のチューニング:Windows APIとの連携

さらに処理を高速化したい場合や、ファイルシステムへのI/Oを最適化したい場合、`Scripting.FileSystemObject`(FSO)に頼りすぎないことも重要だ。

  • ADODB.Streamの活用: FSOの`ReadAll`は巨大なログファイルに対してはメモリを食い尽くす。`ADODB.Stream`でバイナリとして読み込み、バッファリング制御を行うことで、メモリ効率を劇的に改善できる。
  • Dictionaryの限界を知る: 100万件を超えるデータセットを扱うなら、VBScriptの限界は近い。その際はSQLite(`System.Data.SQLite`)や、外部の高速なコマンドラインツール(`grep`や`awk`のWindows移植版)を呼び出し、VBScriptは「オーケストレーター」に徹するべきだ。

5. アーキテクトからの提言

VBScriptは「終わった技術」ではない。「OSの深部にまで届く、軽量なランタイム」として再評価すべきだ。

エンジニアとして恥ずべきは、技術の古さではなく、その技術のポテンシャルを最大限に引き出せず、計算量を無視したアルゴリズムでシステムを重くすることだ。今日紹介したDictionaryによるハッシュ管理は、その第一歩に過ぎない。

次にあなたがコードを書くとき、そのループは本当に必要なのか? 二重ループを書こうとしている指を止め、Scripting.DictionaryでO(n)に変換できるかを一度だけ自問自答してほしい。それが、プロフェッショナルの矜持だ。

タイトルとURLをコピーしました