2

Project Euler Problem 2を解決する非常に単純なVBプログラムを実行していて、パフォーマンスの時間を計りたいと思っています。私のアプローチは次のとおりです。

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ループで実行している実際の計算は非常に高速であるため、タイマーの精度が不十分で時間を区別できません。この質問に関する情報のいくつかを見つけるかもしれません:プログラムが2回目にはるかに速く実行される原因は何ですか?面白い。「プログラムが2回目より速く実行される」のようなものをグーグルで検索すると、キャッシュが原因であることを示す多くの応答が表示されます。

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