【问题标题】:VBS automatic optimizationVBS自动优化
【发布时间】:2015-01-23 02:05:55
【问题描述】:

我正在运行一个非常简单的 VB 程序来解决 Project Euler Problem 2 并且我想计时性能。我的做法是:

StartTime = Timer()
Set streamer = CreateObject("Scripting.FileSystemObject")
Set writingWriter = streamer.GetStandardStream(1)
Dim n, nIterations, Temp1, Temp2, Collector
n = 4000000
nIterations = 0
Temp1 = 0
Collector = 0
Temp2 = 1

Do
    Fib = Temp1 + Temp2
    Temp2 = Temp1
    Temp1 = Fib
    Select Case Fib Mod 2
        Case 0
            Collector = Collector + Fib
    End Select
Loop Until Fib > n
EndTime = Timer()
writingWriter.WriteLine("Solution is: " & Collector)
writingWriter.WriteLine("Code took " & EndTime - StartTime & " to execute")

我第一次运行代码时得到以下输出(我的输入也包括在内):

C:\Dev\cscript program.vbs
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.

Solution is: 4613732
Code took 0.015625 to execute

每次后续执行(不改变任何东西)都会给我以下信息:

C:\Dev\cscript program.vbs
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.

Solution is: 4613732
Code took 0 to execute

有人可以解释这里发生了什么吗?似乎 Windows 控制台已经存储了 Fib 的值,并且只是在执行代码时调用它。一位朋友运行类似的东西(尽管他使用 VBA)得到了相同的结果 - 他随后的每次执行都经历了运行时间的减少。

请注意:我知道这是一种非常简单的方法,我只是想了解一下 VB。到目前为止还不是一个超级粉丝。

【问题讨论】:

  • VBScript 是您可以选择学习 VB 的最糟糕的环境,因为您的开发环境通常是记事本,而不是可以为您建议对象和语法检查的 IDE。如果您的目标是将 VB 作为一门语言学习,那么 MS Office 或 Visual Studio Express 中的 VBA 将是更好的选择。
  • @JamesSnell 感谢您的提示。我想我给 VBA 一个机会。我只是不喜欢打开 Excel。我会使用 Visual Studio,但没有管理员权限就无法安装。

标签: vb.net performance vba optimization


【解决方案1】:

问题不在于 Fib。尽管您没有声明它,但它会在计算中使用它时立即使用默认值。一旦你的脚本结束,它就会超出范围。您的程序的主要瓶颈区域是:

Set streamer = CreateObject("Scripting.FileSystemObject")
Set writingWriter = streamer.GetStandardStream(1)

一旦它第一次运行,它就能够在不久之后更快地执行相同的操作,这可能是由于数据缓存在 RAM 中。

您在 Do 循环中进行的实际计算发生得太快,以至于您的计时器不够精确,无法区分时间。您可能会发现有关此问题的一些信息:What can cause a program to run much faster the 2nd time? 有趣。如果你在谷歌上搜索“程序第二次运行速度更快”之类的内容,你会看到很多响应表明缓存是罪魁祸首。

【讨论】:

  • 感谢您的回复!我已经用谷歌搜索了这个问题,但没有考虑将我的搜索范围扩大到一般情况。您提供的链接是一个很好的阅读(仍在通过它)。
【解决方案2】:

您回答了自己的问题:

Windows 控制台似乎已经存储了 Fib 的值,并且只是在执行代码时调用它。

如果您在退出之前没有清除 Fib 并且让控制台保持打开状态,那么它仍然在临时内存中的某个位置。

解决办法:

StartTime = Timer()
Set streamer = CreateObject("Scripting.FileSystemObject")
Set writingWriter = streamer.GetStandardStream(1)
Dim n, nIterations, Temp1, Temp2, Collector
n = 4000000
nIterations = 0
Temp1 = 0
Collector = 0
Temp2 = 1

Do
    Fib = Temp1 + Temp2
    Temp2 = Temp1
    Temp1 = Fib
    Select Case Fib Mod 2
        Case 0
            Collector = Collector + Fib
    End Select
Loop Until Fib > n
EndTime = Timer()
writingWriter.WriteLine("Solution is: " & Collector)
writingWriter.WriteLine("Code took " & EndTime - StartTime & " to execute")
streamer = NULL
writingWriter = NULL
Fib = 0

【讨论】:

  • 非常酷 - 感谢您的帮助!但是,将 Fib 设置为零似乎并不能解决问题。有没有办法直接清除临时内存?也许如果有固定的空间,我可以简单地运行一个脚本来超载临时内存并强制淘汰旧的东西?
猜你喜欢
  • 1970-01-01
  • 2014-11-18
  • 2018-06-15
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 2021-02-21
相关资源
最近更新 更多