【テクニカル・上級編】【処理速度最適化】大量ファイル処理におけるFSOオブジェクト再生成の防止と文字列結合の高速化 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptの深淵:FSOの再生成を排し、メモリの鼓動を制御せよ

レガシーシステムの墓場と揶揄されることもあるVBScript。しかし、その正体はWindowsカーネルのすぐ側に位置する、極めて軽量かつ強力なインターフェースだ。多くのエンジニアが「遅い」と切り捨てるそのパフォーマンスは、実は言語の限界ではなく、実装の甘さという名の「技術的負債」にすぎない。

今日は、数万件のファイル処理や巨大なログ集計を、VBScriptで「爆速」に変えるためのアーキテクチャ設計について語る。

—

1. CreateObjectの呪縛を解く:インスタンスのライフサイクル管理

多くの未熟なコードに見られるのが、ループ内で`CreateObject(“Scripting.FileSystemObject”)`を繰り返すという愚行だ。これを行うたびに、COM(Component Object Model)のランタイムはレジストリを走査し、新しいインスタンスをメモリ上に展開する。

アンチパターン:

‘ 悪夢のような遅延を招くコード
For Each f In folder.Files
Set fso = CreateObject(“Scripting.FileSystemObject”) ‘ ループ内での生成は死を意味する
‘ … 処理 …
Set fso = Nothing
Next

【解法】オブジェクトの永続化

FSOインスタンスは、スクリプトの冒頭で一度だけ生成し、グローバル変数としてスコープの最後まで使い回せ。これはメモリ管理の基本であり、Windowsのプロセス内でCOMオブジェクトを再利用することで、オーバーヘッドをゼロに近づける。

‘ 最適化された実装
Dim fso : Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 処理終了までインスタンスを維持する
ProcessFiles(fso)

‘ スクリプト終了時に明示的に解放する(VBScriptでは必須ではないが、大規模な場合は習慣化せよ)
Set fso = Nothing

—

2. 文字列結合の闇:`&` 演算子の限界を超えて

大量のデータをCSVとして書き出す際や、ログを生成する際、`s = s & newString` という記述を繰り返していないか?

VBScriptの文字列は不変(Immutable)だ。`&` を使うたびに、メモリ上の古い領域を捨て、新しいサイズでメモリを再確保し、全データをコピーし直すという膨大なコストが発生する。データ量が増えるほど指数関数的に遅くなるのは必然だ。

【解法】配列と `Join` 関数の活用

メモリを一度だけ確保し、その中にデータを詰め込む。これが最速の解法だ。`Array`をバッファとして使い、最後に`Join`関数で一気に結合する。

Dim results()
ReDim results(10000) ‘ 事前にサイズを確保(動的拡張のコストを抑える)
Dim i : i = 0

For Each f In folder.Files
results(i) = f.Name & “,” & f.Size
i = i + 1
Next

‘ 最後に結合して出力(文字列再生成を最小化)
WScript.Echo Join(results, vbCrLf)

—

3. Windows APIによるファイル操作の極致

FSOは便利だが、数百万件を超える大規模なファイルリストの取得において、`Folder.Files`コレクションをループさせるのはメモリ消費が激しい。VBScriptからWindows API(`ScriptControl`経由やWMI、あるいはコマンドシェル)を組み合わせて活用する視点を持て。

特に、`Dir`コマンドの結果をパイプで受け取る手法は、オブジェクトを生成せずにメモリを抑えるテクニックとして有効だ。

‘ FSOに頼らない超高速なファイルリスト取得の思考
Dim shell : Set shell = CreateObject(“WScript.Shell”)
Dim cmd : cmd = “cmd /c dir /b /a-d C:\TargetFolder”
Dim oExec : Set oExec = shell.Exec(cmd)

‘ ストリームで読み込むことでメモリ消費を極限まで抑える
Do While Not oExec.StdOut.AtEndOfStream
Dim line : line = oExec.StdOut.ReadLine
‘ ここで逐次処理を行う
Loop

—

結論:シニアエンジニアとしての「美学」

VBScriptは、今なおWindowsの自動化において、最も身軽な武器であり続けている。
遅いのではない。あなたの書くコードが、計算機科学の原則を忘れているだけだ。

1. インスタンスは一度だけ生成せよ。
2. 文字列操作は配列でバッファせよ。
3. オブジェクトのオーバーヘッドを意識せよ。

これらを守るだけで、あなたのスクリプトは、現代の肥大化したプログラムたちを尻目に、静かに、かつ圧倒的な速度でタスクを完了させるだろう。レガシーを愛せ。そして、それを最高峰のパフォーマンスで制御せよ。それがプロフェッショナルの仕事だ。

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