none
VBSの変数に格納可能な文字列の最大バイト数は? RRS feed

  • 質問

  • お世話になります。

    タイトルの通り、VBSの変数に格納可能な文字列の最大バイト数は何バイトでしょうか。どこかの質問投稿サイトには2GBという記述とMSのサイトURLがはってありましたが、もうそのURLは存在しないようでして。。。

    ある変数に文字列を詰め込んで一気にテキストファイルに書き込もうとしています。

    背景は以下です。

    VBSを用いて、複数のテキストファイルの一部(ある区間だけ)を1つのファイルにマージする処理をさせようとしています。

    書き込みの回数を減らしたいため、マージの対象のファイル1つにつき1回の書き込みで済ませたいと思っています。

    ロジックとしては以下を想定しています。

    1.マージの対象のファイルを一行ずつ読み取り、マージする行であった場合は変数aに文字列として格納する。

    格納の仕方は既存の値の後ろに追加する形にする。(a=a+格納する文字列)

    1つのファイル全てに対して読み取りが終わったら、新しくテキストファイルを作成し、変数aに格納されている値を一度に書き込む(何十MB分か一気に書き込むイメージです)。

    2015年6月2日 9:11

回答

  • 論理上の制限値は約 2GB です。ただし、実際にそこまで耐えられるかどうかは環境依存です。

    【VBScript のデータ型】
    https://msdn.microsoft.com/ja-jp/library/cc392195.aspx

    > (a=a+格納する文字列)

    その方法は現実的では無いと思います。「文字列の連結」は比較的低速なので

    s = String(524288, "あ")  '約50万文字(1MB相当)の文字列
    For i = 1 To 5000
      s = s & "あ"
    Next

    以下、当方環境での計測結果:

    1MBから開始、ループ回数5千 → 約1.7秒
    1MBから開始、ループ回数1万 → 約3.5秒
    1MBから開始、ループ回数2万 → 約7.0秒

    2MBから開始、ループ回数5千 → 約3.5秒
    2MBから開始、ループ回数1万 → 約6.8秒
    2MBから開始、ループ回数2万 → 約14.0秒

    4MBから開始、ループ回数5千 → 約6.9秒
    4MBから開始、ループ回数1万 → 約13.9秒
    4MBから開始、ループ回数2万 → 約27.9秒

    この場合は『文字列連結』で処理するのではなく、マージ結果を出力するためのテキストファイルに、直接『追記』していった方が良いでしょう。
    処理速度が早いだけではなく、消費メモリも圧倒的に少なくて済みます。

    s = String(2097152, "あ")
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set MyFile= fso.CreateTextFile("c:\temp\testfile.txt", True)
    MyFile.Write s
    For i = 1 To 20000
      MyFile.Write "あ"
    Next
    MyFile.Close
    

    当方環境での計測結果は以下の通り:

    1MBから開始、ループ回数5千 → 約0.01秒
    512MBから開始、ループ回数50万 → 約9.8秒

    • 回答としてマーク 星 睦美 2015年6月11日 6:49
    2015年6月2日 10:41
  • 仕様などの情報があるかはわかりませんが、基本的に、仕様と実用上の限度は異なるということに注意しておく必要があります。
    2GBはそもそもまともに動作しないでしょう。

    文字列の連結処理も、VBAでどうだったか把握していませんが、とてつもなく遅くなる可能性もある気がします。

    またファイルにまとめて書くのも、もしパフォーマンス目的なのであれば、数十MB以上まとめて書くことにはあまり意味はありません。

    プログラム観点では数十KB程度まとめての書き込みであればまず十分でしょう(ネットワーク経由の場合はやや状況が違ったりすることはありますが)。

    通常はOS側でキャッシュされますので、ディスクアクセスとプログラムからの書き込みサイズはイコールではありませんし、逆に書き込みが大きすぎると、キャッシュ(遅延書き込み)が効かなくなって余計遅くなったりしますよ。

    • 回答としてマーク 星 睦美 2015年6月11日 6:49
    2015年6月2日 9:52
  • VBScript のデータ型には

    約 2GB までの文字を格納できる可変長文字列を持つデータ型です。

    と説明されています。

    • 回答としてマーク 星 睦美 2015年6月11日 6:49
    2015年6月2日 9:53

すべての返信

  • 仕様などの情報があるかはわかりませんが、基本的に、仕様と実用上の限度は異なるということに注意しておく必要があります。
    2GBはそもそもまともに動作しないでしょう。

    文字列の連結処理も、VBAでどうだったか把握していませんが、とてつもなく遅くなる可能性もある気がします。

    またファイルにまとめて書くのも、もしパフォーマンス目的なのであれば、数十MB以上まとめて書くことにはあまり意味はありません。

    プログラム観点では数十KB程度まとめての書き込みであればまず十分でしょう(ネットワーク経由の場合はやや状況が違ったりすることはありますが)。

    通常はOS側でキャッシュされますので、ディスクアクセスとプログラムからの書き込みサイズはイコールではありませんし、逆に書き込みが大きすぎると、キャッシュ(遅延書き込み)が効かなくなって余計遅くなったりしますよ。

    • 回答としてマーク 星 睦美 2015年6月11日 6:49
    2015年6月2日 9:52
  • VBScript のデータ型には

    約 2GB までの文字を格納できる可変長文字列を持つデータ型です。

    と説明されています。

    • 回答としてマーク 星 睦美 2015年6月11日 6:49
    2015年6月2日 9:53
  • 論理上の制限値は約 2GB です。ただし、実際にそこまで耐えられるかどうかは環境依存です。

    【VBScript のデータ型】
    https://msdn.microsoft.com/ja-jp/library/cc392195.aspx

    > (a=a+格納する文字列)

    その方法は現実的では無いと思います。「文字列の連結」は比較的低速なので

    s = String(524288, "あ")  '約50万文字(1MB相当)の文字列
    For i = 1 To 5000
      s = s & "あ"
    Next

    以下、当方環境での計測結果:

    1MBから開始、ループ回数5千 → 約1.7秒
    1MBから開始、ループ回数1万 → 約3.5秒
    1MBから開始、ループ回数2万 → 約7.0秒

    2MBから開始、ループ回数5千 → 約3.5秒
    2MBから開始、ループ回数1万 → 約6.8秒
    2MBから開始、ループ回数2万 → 約14.0秒

    4MBから開始、ループ回数5千 → 約6.9秒
    4MBから開始、ループ回数1万 → 約13.9秒
    4MBから開始、ループ回数2万 → 約27.9秒

    この場合は『文字列連結』で処理するのではなく、マージ結果を出力するためのテキストファイルに、直接『追記』していった方が良いでしょう。
    処理速度が早いだけではなく、消費メモリも圧倒的に少なくて済みます。

    s = String(2097152, "あ")
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set MyFile= fso.CreateTextFile("c:\temp\testfile.txt", True)
    MyFile.Write s
    For i = 1 To 20000
      MyFile.Write "あ"
    Next
    MyFile.Close
    

    当方環境での計測結果は以下の通り:

    1MBから開始、ループ回数5千 → 約0.01秒
    512MBから開始、ループ回数50万 → 約9.8秒

    • 回答としてマーク 星 睦美 2015年6月11日 6:49
    2015年6月2日 10:41