2

我正在运行一个非常简单的 VB 程序来解决 Project Euler问题 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。到目前为止还不是一个超级粉丝。

4

2 回答 2

1

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

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

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

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

于 2012-12-18T16:44:26.733 回答
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
于 2012-12-18T16:29:22.807 回答