2

I am running a pretty simple VB program that solves the Project Euler Problem 2 and I want to time the performance. My approach is:

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")

The first time I ran the code I got the following output (my input is also included):

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

Each subsequent execution (not changing anything) gives me the following:

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

Can someone explain what is going on here? It seems like the Windows Console has stored the value of Fib and is simply recalling it upon execution of the code. A friend running something similar (although he's using VBA) got the same result - each of his subsequent executions experienced a reduction in run-time.

Please note: I know this is a pretty simple approach, I'm just trying to get a feel for VB. Not a huge fan so far.

galois
  • 142
  • 1
  • 7
  • VBScript is about the worst environment you could chosen to learn VB since your development environment is generally notepad rather than an IDE which can suggest objects and syntax check for you. If your goal is to learn VB as a language then VBA in MS Office or Visual Studio Express will be better options. – James Snell Dec 18 '12 at 17:10
  • @JamesSnell Thanks for the tip. I guess I give VBA a shot. I just don't like having to open up Excel. I would use Visual Studio but can't install that without Admin privileges. – galois Dec 18 '12 at 18:15

2 Answers2

1

The issue is not Fib. Though you do not declare it, it uses the default value as soon as it is used in a calculation. Once your script ends, it goes out of scope. The main bottleneck area for your program is this:

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

Once it runs the first time, it is able to perform the same action much faster shortly there after probably due to data cached in RAM.

The actual calculations that you are doing in your Do loop happen so quickly that your timer is insufficiently precise to distinguish the time. You may find some of the information on this question: What can cause a program to run much faster the 2nd time? interesting. If you google something like "program runs faster the 2nd time", you will see a lot of responses indicating caching as the culprit.

Community
  • 1
  • 1
Daniel
  • 12,982
  • 3
  • 36
  • 60
  • Thanks for the response! I had googled this issue but didn't think to expand my searching scope to the general case. The link you provided is a great read (still working through it). – galois Dec 18 '12 at 18:11
0

You answered your own question:

It seems like the Windows Console has stored the value of Fib and is simply recalling it upon execution of the code.

If you're not clearing Fib before you exit and you leave the console open, it is still somewhere in temporary memory.

A fix is to do:

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
redhotspike
  • 1,056
  • 5
  • 17
  • 39
  • 1
    Very cool - thanks for the help! However, setting Fib equal to zero does not seem to solve the problem. Is there a way to directly clear the temporary memory? Maybe if there is fixed space I could simply run a script that overloads the temporary memory and forces out the old stuff? – galois Dec 18 '12 at 16:33