VBS自动优化

时间:2012-12-18 16:21:31

标签: vb.net performance vba optimization

我正在运行一个非常简单的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。到目前为止,并不是一个巨大的粉丝。

2 个答案:

答案 0 :(得分: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?有趣。如果你谷歌的话“第二次程序跑得更快”,你会看到很多回复表明缓存是罪魁祸首。

答案 1 :(得分:0)

你回答了自己的问题:

  

似乎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
相关问题