VB.NET-Tipp 0140: Ausführungsgeschwindigkeit von Codeabschnitten bestimmen
von Spatzenkanonier
Beschreibung
Bei der Untersuchung der Ausführungsgeschwindigkeit bestimmter Code-Abschnitte zeigt die übliche System.StopWatch eine gewisse Unhandlichkeit, da hin und wieder Zeiten bis hinunter in den Mikrosekunden-Bereich (10^-6 s) zu ermitteln sind. Man kann sich behelfen, indem man die Funktion mehrfach ausführt und somit die Summe der Laufzeiten erhält. Für diese Vorgehensweise sollte man die für einen Durchlauf benötigte Zeit jedoch recht gut abschätzen, da man ansonsten möglicherweise eine viel zu hohe Anzahl von Wiederholungen festlegt und ziemlich lange auf deren Beendingung warten muss.
Dieser Tipp stellt ein besseres Vorgehen vor: Vorgegeben wird eine Zeit und die Schleife wird nach Ablauf derselben verlassen.
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5, .NET Compact Framework 1.0, .NET Compact Framework 2.0, .NET Framework 4 | .NET-Version(en): Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008, Visual Basic 2010 | Download: |
' Dieser Quellcode stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' Projektversion: Visual Studio 2005 ' Option Strict: An ' ' Referenzen: ' - System ' - System.Data ' - System.Drawing ' - System.Windows.Forms ' - System.Xml ' ' Imports: ' - Microsoft.VisualBasic ' - Microsoft.VisualBasic.ControlChars ' - System ' - System.Collections ' - System.Collections.Generic ' - System.Data ' - System.Drawing ' - System.Diagnostics ' - System.Windows.Forms ' ' ############################################################################## ' ############################# BenchmarkTimer.vb ############################## ' ############################################################################## ''' <summary> ''' Nutzung: eine zeitkritische Funktion mit einer While BenchmarkTimer.Runs()- ''' Schleife umschließen. Die Console-Ausgabe gibt an, wie oft die Funktion ''' innerhalb der gegebenen Zeit ausgeführt werden konnte ''' </summary> Public Class BenchmarkTimer Private Shared _Counter As Integer Private Shared _LastTick As Integer = Integer.MinValue Public Shared Function Runs(ByVal RunTime As Integer, _ Optional ByVal Msg As String = "BenchmarkTimer") As Boolean If Environment.TickCount < _LastTick Then _Counter += 1 ElseIf _LastTick = Integer.MinValue Then _LastTick = Environment.TickCount + RunTime _Counter = 0 Else Console.WriteLine(String.Concat(Msg, ": ", _Counter)) _LastTick = Integer.MinValue Return False End If Return True End Function End Class ' ############################################################################## ' ########################### BenchmarkWatch.vbproj ############################ ' ############################################################################## <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProductVersion>8.0.50727</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{89B5F3CA-7033-4490-9763-21C60FE1DC83}</ProjectGuid> <OutputType>WinExe</OutputType> <StartupObject>BenchmarkWatch.My.MyApplication</StartupObject> <RootNamespace>BenchmarkWatch</RootNamespace> <AssemblyName>BenchmarkWatch</AssemblyName> <MyType>WindowsForms</MyType> <OptionStrict>On</OptionStrict> <PublishUrl>http://localhost/BenchmarkWatch/</PublishUrl> <Install>True</Install> <InstallFrom>Web</InstallFrom> <UpdateEnabled>True</UpdateEnabled> <UpdateMode>Foreground</UpdateMode> <UpdateInterval>7</UpdateInterval> <UpdateIntervalUnits>Days</UpdateIntervalUnits> <UpdatePeriodically>False</UpdatePeriodically> <UpdateRequired>False</UpdateRequired> <MapFileExtensions>True</MapFileExtensions> <ApplicationVersion>1.0.0.%2a</ApplicationVersion> <IsWebBootstrapper>True</IsWebBootstrapper> <BootstrapperEnabled>True</BootstrapperEnabled> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>True</DebugSymbols> <DebugType>full</DebugType> <DefineDebug>True</DefineDebug> <DefineTrace>True</DefineTrace> <OutputPath>bin\Debug\</OutputPath> <DocumentationFile>BenchmarkWatch.xml</DocumentationFile> <NoWarn> </NoWarn> <WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> <DefineDebug>False</DefineDebug> <DefineTrace>True</DefineTrace> <Optimize>True</Optimize> <OutputPath>bin\Release\</OutputPath> <DocumentationFile>BenchmarkWatch.xml</DocumentationFile> <NoWarn> </NoWarn> <WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors> </PropertyGroup> <ItemGroup> <Reference Include="System" /> <Reference Include="System.Data" /> <Reference Include="System.Drawing" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> <Import Include="Microsoft.VisualBasic" /> <Import Include="Microsoft.VisualBasic.ControlChars" /> <Import Include="System" /> <Import Include="System.Collections" /> <Import Include="System.Collections.Generic" /> <Import Include="System.Data" /> <Import Include="System.Drawing" /> <Import Include="System.Diagnostics" /> <Import Include="System.Windows.Forms" /> </ItemGroup> <ItemGroup> <Compile Include="BenchmarkTimer.vb" /> <Compile Include="frmBenchmarkWatch.vb"> <SubType>Form</SubType> </Compile> <Compile Include="frmBenchmarkWatch.Designer.vb"> <DependentUpon>frmBenchmarkWatch.vb</DependentUpon> <SubType>Form</SubType> </Compile> <Compile Include="My Project\AssemblyInfo.vb" /> <Compile Include="My Project\Application.Designer.vb"> <AutoGen>True</AutoGen> <DependentUpon>Application.myapp</DependentUpon> </Compile> <Compile Include="My Project\Resources.Designer.vb"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> <DependentUpon>Resources.resx</DependentUpon> </Compile> <Compile Include="My Project\Settings.Designer.vb"> <AutoGen>True</AutoGen> <DependentUpon>Settings.settings</DependentUpon> <DesignTimeSharedInput>True</DesignTimeSharedInput> </Compile> </ItemGroup> <ItemGroup> <EmbeddedResource Include="frmBenchmarkWatch.resx"> <SubType>Designer</SubType> <DependentUpon>frmBenchmarkWatch.vb</DependentUpon> </EmbeddedResource> <EmbeddedResource Include="My Project\Resources.resx"> <Generator>VbMyResourcesResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.vb</LastGenOutput> <CustomToolNamespace>My.Resources</CustomToolNamespace> <SubType>Designer</SubType> </EmbeddedResource> </ItemGroup> <ItemGroup> <None Include="My Project\Application.myapp"> <Generator>MyApplicationCodeGenerator</Generator> <LastGenOutput>Application.Designer.vb</LastGenOutput> </None> <None Include="My Project\Settings.settings"> <Generator>SettingsSingleFileGenerator</Generator> <CustomToolNamespace>My</CustomToolNamespace> <LastGenOutput>Settings.Designer.vb</LastGenOutput> </None> </ItemGroup> <ItemGroup> <BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> <Visible>False</Visible> <ProductName>.NET Framework 2.0</ProductName> <Install>True</Install> </BootstrapperPackage> <BootstrapperPackage Include="Microsoft.Sql.Server.Express.1.0"> <Visible>False</Visible> <ProductName>SQL Server 2005 Express Edition</ProductName> <Install>True</Install> </BootstrapperPackage> <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> <Visible>False</Visible> <ProductName>Windows Installer 3.1</ProductName> <Install>True</Install> </BootstrapperPackage> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" /> <!-- To modify your build process, add your task inside one Of the targets below And uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> --> </Project> ' ############################################################################## ' ########################### frmBenchmarkWatch.vb ############################# ' ############################################################################## Imports System.IO Public Class frmBenchmarkWatch Private Src1 As String, Src2 As String Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles MyBase.Load Dim DirUp As String = ".." & Path.DirectorySeparatorChar Src1 = String.Concat(DirUp, DirUp, "frmBenchmarkWatch.vb") Src1 = Path.GetFullPath(Src1) Src2 = Application.ExecutablePath lbWhatsTested.Text = String.Concat("vergleiche Einlesen der Datei:", _ Lf, Src1, Lf, "mit Einlesen von:", Lf, Src2) End Sub Private Sub btTest_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles btTest.Click ' Teste die Einlese-Geschwindigkeit zweier verschiedener Files Dim Buf(&HFF) As Byte While BenchmarkTimer.Runs(1000, "load Src1") Using FS As New FileStream(Src1, FileMode.Open, FileAccess.Read) Do FS.Read(Buf, 0, Buf.Length) Loop Until FS.Position = FS.Length End Using End While While BenchmarkTimer.Runs(1000, "load Src2") Using FS As New FileStream(Src2, FileMode.Open, FileAccess.Read) Do FS.Read(Buf, 0, Buf.Length) Loop Until FS.Position = FS.Length End Using End While End Sub Private Sub btTestEmpty_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles btTestEmpty.Click While BenchmarkTimer.Runs(1000, "EmptyTest") ' Je größer der Unterschied zwischen Leertest und Echt-Test- ' Ergebnissen, desto mehr Aussagekraft haben Letztere End While End Sub End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.