<%
' Class library for timing sections of ASP code.
'
' Create instances of the SlTimerScope class in your code and make sure the lifetime of the instances matches
' what you want to time.
' You provide this class with an instance of the SlTimerContext class
' which you should keep alive for the life of your page.
' Call on the context class's Scopes property to get a dictionary containing SlTimerContextItem classes
' which hold information about the timing of the scopes,
' or just call the SummarizeTiming routine at the bottom of this file for a nice little tabular report.
' You can provide the SlTimerScope class with a "nothing" context to disable the more time-consuming
' profiling operations and the summary output.
'
' Instead of using the SlTimerScope class, you can use the SlTimerContext class's
' EnterScope and ExistScope methods directly.
' The main benefit of having a scope class is that you can just declare instances of the class
' in a function you want to time without worrying about calling ExitScope at all return points
' or in case of untrapped errors, etc., but for timing small sections of long scripts,
' the context methods are a bit more succinct.
' Timer scope class.
class SlTimerScope
Public Context
Public ScopeName
Public Sub Enter(ScopeNameParam, ContextParam)
Set Context = ContextParam
ScopeName = ScopeNameParam
If Not Context Is Nothing Then
Context.EnterScope ScopeName
End If
End Sub
Private Sub Class_Terminate()
If Not Context Is Nothing Then
Context.ExitScope ScopeName
End If
End Sub
end class
' Timer context class.
' Manages a global set of timer scopes.
class SlTimerContext
' Schema: Scope => SlTimerContextItem.
Private m_timerScopes
Public Sub ResetScopes
m_timerScopes.RemoveAll
End Sub
Public Sub EnterScope(ScopeName)
Dim timer_obj
If m_timerScopes.Exists(ScopeName) Then
Set timer_obj = m_timerScopes(ScopeName)
Else
Set timer_obj = New SlTimerContextItem
timer_obj.ScopeName = ScopeName
Set timer_obj.TimerObj = New SlTimer
m_timerScopes.Add ScopeName, timer_obj
End If
timer_obj.EnterScope
End Sub
Public Sub ExitScope(ScopeName)
Dim timer_obj
Set timer_obj = m_timerScopes(ScopeName)
timer_obj.ExitScope
End Sub
Public Property Get Scopes
Set Scopes = m_timerScopes
End Property
Private Sub Class_Initialize()
Set m_timerScopes = Server.CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate()
ResetScopes
Set m_timerScopes = Nothing
End Sub
end class
' Timer context item. This holds information about the scope it represents.
class SlTimerContextItem
Public ScopeName
Public ElapsedMs
Public TimerObj
Public HitCount
Public Sub EnterScope
HitCount = HitCount + 1
TimerObj.StartTimer
End Sub
Public Sub ExitScope
TimerObj.StopTimer
ElapsedMs = ElapsedMs + TimerObj.ElapsedMs
End Sub
end class
' Core timer class. Wraps the Softwing.Profiler component providing a nice Start, Stop, ElapsedMs interface.
class SlTimer
Private m_timer
Private m_latestElapsedMs
Private Sub Class_Initialize()
Set m_timer = CreateObject("Softwing.Profiler")
End Sub
Public Sub StartTimer()
m_timer.ProfileStart
End Sub
Public Sub StopTimer()
m_latestElapsedMs = m_timer.ProfileStop / 10
End Sub
Public Property Get ElapsedMs()
ElapsedMs = m_latestElapsedMs
End Property
end class
' Utility function to summarize the scopes.
sub SummarizeTiming(timerCtxt)
if timerCtxt is nothing then
exit sub
end if
Dim scopes
Set scopes = timerCtxt.Scopes
%>
SlTiming Info
Scope Total Time (ms) Total Hits Time Per Hit (ms/hit)
<%
Dim cur_scope
for each cur_scope in scopes.Items
with cur_scope
%>
<% = Server.HtmlEncode(.ScopeName) %>
<% = FormatNumber(.ElapsedMs) %>
<% = .HitCount %>
<%
if .HitCount = 0 then
Response.Write "???"
else
Response.Write FormatNumber(.ElapsedMs / .HitCount)
end if
%>
<%
end with
next
%>
<%
end sub
%>