【问题标题】:vbscript optimization : how to get faster file writingvbscript 优化:如何获得更快的文件写入
【发布时间】:2009-02-03 02:17:58
【问题描述】:

以下是我在许多 vbscripts 中使用的常用日志功能,我对此进行了相应修改。感觉写的太慢了我有 3 个问题:

  1. 关于如何优化它以使其写入更快的任何想法?
  2. 首先将所有文本存储在一个字符串中然后运行函数 OutputToLog 会更快,还是每次我需要将字符串插入文本文件时执行 OutputToLog 会更快?
  3. 如果驱动器空间不是一个因素,在执行期间写入文本文件时是否可能会耗尽内存...导致脚本执行速度越来越慢?

这是我的 vbscript 函数

Function OutputToLog (strToAdd)  
    Dim strDirectory,strFile,strText, objFile,objFolder,objTextFile,objFSO
    strDirectory = "c:\log"
    strFile = "\log-"& StampNow &  ".bat"
    'strText = "test"
    strText = strToAdd

    ' Create the File System Object
    Set objFSO = CreateObject("Scripting.FileSystemObject")

    ' Check that the strDirectory folder exists
    If objFSO.FolderExists(strDirectory) Then
       Set objFolder = objFSO.GetFolder(strDirectory)
    Else
       Set objFolder = objFSO.CreateFolder(strDirectory)
       'WScript.Echo "Just created " & strDirectory
    End If

    If objFSO.FileExists(strDirectory & strFile) Then
       Set objFolder = objFSO.GetFolder(strDirectory)
    Else
       Set objFile = objFSO.CreateTextFile(strDirectory & strFile)
       'Wscript.Echo "Just created " & strDirectory & strFile
    End If

    set objFile = nothing
    set objFolder = nothing
    ' OpenTextFile Method needs a Const value
    ' ForAppending = 8 ForReading = 1, ForWriting = 2
    Const ForAppending = 8

    Set objTextFile = objFSO.OpenTextFile _
    (strDirectory & strFile, ForAppending, True)

    ' Writes strText every time you run this VBScript
    objTextFile.WriteLine(strText)
    objTextFile.Close
End Function

提前致谢

【问题讨论】:

  • 您不必检查文件是否存在,只要将True作为第三个参数传递,OpenTextFile就会创建文件如果它不存在。它可能不会节省很多时间,但会节省一些打字时间。

标签: optimization vbscript


【解决方案1】:

我认为您既希望创建 FSO 对象,又希望在 OutputToLog 函数之外打开日志文件。它可能不会节省太多时间,但为什么要在每次写入时创建对象、打开和关闭文件?

否则,如果您想保持功能不变,只写一次应该会更快。

【讨论】:

  • +1 打开 / 扫描 / 关闭是 windows 上最具成本效益的操作,因此您可以放心。此外,代码看起来可以通过保持使用来使用独占访问。
  • 其实和Martijn说的正好相反。从 Windows NT 开始,打开、追加和关闭是 Windows 一直非常快的操作。即使是低端系统也可以轻松地打开一个日志文件,将一行文本附加到它上面,然后以每秒 100 到 200 次的速度再次关闭它,而不会随着文件的增长而明显减慢速度。我当前的系统在写入硬盘时每个周期大约需要 4 毫秒,或者在写入 SSD 时需要 3 毫秒。
  • 澄清一下——我之前的评论并不意味着你不会通过优化代码来获得更好的执行时间。我的意思是,打开/追加/关闭的执行速度比您预期的“最高成本”要快得多,因此速度优势并没有那么大。我会做与建议相反的事情,如果只是为了确保我的日志文件可以在任何时候被检查,也在执行过程中,并且如果应用程序崩溃或被杀死而没有允许它被杀死,它的所有内容都完好无损。干净地关闭文件。
【解决方案2】:

如果您正在执行大量小型写入,那么重构对 FolderExists 和 FileExists 的检查会有所帮助。也许尝试写入文件,捕获任何错误,并在错误处理程序中检查 FolderExists 和 FileExists 并在必要时创建它们?

输出一个大字符串比输出几个小字符串要快,但您必须权衡它与程序崩溃时丢失日志条目的可能性。

除非您向文件写入 humungous 字符串,否则内存不应该成为问题,甚至可能不会。

因为您要附加到文件,所以日志文件越长,写入所需的时间就越长,因为(AFAIK)每次都必须重写整个文件。这是减少编写较长字符串的另一个原因。

您能改用 Windows 的事件日志吗?

【讨论】:

  • 创建较小的文件然后在过程结束时将它们全部合并会更快吗?
  • 我不能使用事件日志,因为我正在使用日志文件来构建一个批处理文件以便之后运行。在一个实例中,我发现创建并执行 xcopy 命令的批处理文件比在 vbscript 中使用 copyfile 对象更容易。
  • 我刚刚修改了一个脚本,在执行上述函数之前将所有内容存储在一个字符串中。目前似乎进展得更快。我想我们真的会看到接下来的 2 个小时左右会发生什么。在输出到文件之前,它必须筛选 50 gigs 的文件和文件夹。
  • 写入本身并不是最具成本效益的操作打开/扫描(甚至eof)/关闭文件通常会减慢文件访问速度。
【解决方案3】:

在准备函数中检查和创建所有文件夹/文件,然后您可以安全地附加到日志文件中,知道它会在那里吗?此外,您应该能够只创建一次 fso 对象。

类似下面的代码(未经测试的代码)

Dim loggerFSO

Function PrepLog
    dim objFolder
    ' Create the File System Object
    if loggerFSO is nothing then Set loggerFSO = CreateObject("Scripting.FileSystemObject")

    ' Check that the strDirectory folder exists
    If loggerFSO.FolderExists(strDirectory) Then
       Set objFolder = loggerFSO.GetFolder(strDirectory)
    Else
       Set objFolder = loggerFSO.CreateFolder(strDirectory)
       'WScript.Echo "Just created " & strDirectory
    End If

    If loggerFSO.FileExists(strDirectory & strFile) Then
       ' do nothing
    Else
       loggerFSO.CreateTextFile(strDirectory & strFile)
       'Wscript.Echo "Just created " & strDirectory & strFile
    End If
End function

Function OutputToLog (strToAdd)  
    Dim strDirectory,strFile,strText, objTextFile
    strDirectory = "c:\log"
    strFile = "\log-"& StampNow &  ".bat"
    'strText = "test"
    strText = strToAdd

    ' Create the File System Object
    if loggerFSO is nothing then Set loggerFSO = CreateObject("Scripting.FileSystemObject")

    ' OpenTextFile Method needs a Const value
    ' ForAppending = 8 ForReading = 1, ForWriting = 2
    Const ForAppending = 8

    Set objTextFile = loggerFSO.OpenTextFile _
    (strDirectory & strFile, ForAppending, True)

    ' Writes strText every time you run this VBScript
    objTextFile.WriteLine(strText)
    objTextFile.Close
End Function

【讨论】:

    【解决方案4】:

    不要在调用之间关闭文件,让 textstream-object 在它终止时负责关闭。

    Dim OutputToLogFileObject
    Function OutputToLog (strToAdd)  
        Dim strDirectory,strFile,strText, objFile,objFolder,objTextFile,objFSO
        If IsEmpty(OutputToLogFileObject) Then
            strDirectory = "c:\log"
            strFile = "\log-"& StampNow &  ".bat"
            'strText = "test"
            strText = strToAdd
    
            ' Create the File System Object
            Set objFSO = CreateObject("Scripting.FileSystemObject")
    
            ' Check that the strDirectory folder exists
            If objFSO.FolderExists(strDirectory) Then
               Set objFolder = objFSO.GetFolder(strDirectory)
            Else
               Set objFolder = objFSO.CreateFolder(strDirectory)
               'WScript.Echo "Just created " & strDirectory
            End If
    
            If objFSO.FileExists(strDirectory & strFile) Then
               Set objFolder = objFSO.GetFolder(strDirectory)
            Else
               Set objFile = objFSO.CreateTextFile(strDirectory & strFile)
               'Wscript.Echo "Just created " & strDirectory & strFile
            End If
    
            set objFile = nothing
            set objFolder = nothing
            ' OpenTextFile Method needs a Const value
            ' ForAppending = 8 ForReading = 1, ForWriting = 2
            Const ForAppending = 8
    
            Set OutputToLogFileObject = objFSO.OpenTextFile _
            (strDirectory & strFile, ForAppending, True)
        End If
        OutputToLogFileObject.WriteLine strText
     End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      相关资源
      最近更新 更多