Relying on try catch

L

Lloyd Sheen

I noticed a thread a few days ago about the use of Try.. Catch versus
testing variables etc and had in my mind to test exactly what the impact
was. Its a mind boggler.

I created a small windows app that executed two subroutines.

The first simply created an object which does not implement an interface and
attempts to assign that object to an variable of the interface type. This
is done in a try ... catch block.

Private Sub UseTryCatch()
Dim inter As Tester
Dim obj As New WithNoInterface
starttime = Now.Ticks
For i As Integer = 0 To cnt
Try
inter = obj
Catch et As InvalidCastException
Dim iii As Integer = 1
Catch ex As Exception
Dim ii As Integer = 1
End Try
Next
endtime = Now.Ticks
Dim interv As Long
interv = endtime - starttime
Me.TimeCatch.Text = interv.ToString
End Sub

The second creates the same object but uses reflection to test if the object
supports the interface and if so then the assignment would take place.

Private Sub UseReflection()
Dim inter As Tester
Dim obj As New WithNoInterface
starttime = Now.Ticks
For i As Integer = 0 To cnt
Dim typ As Type = obj.GetType
If typ.GetInterface("Tester") IsNot Nothing Then
inter = obj
End If
Next
endtime = Now.Ticks
Dim interv As Long
interv = endtime - starttime
Me.TimeReflection.Text = interv.ToString
End Sub


The results of this test were that the try .. catch took 101087280 ticks
(about 5 seconds on a dual 3.0 G).

The reflection test took 9765 ticks (too fast to determine in my old brain).

The testing before trying was 10352 times faster. I would think that would
put to rest any questions as to the best method of capturing errors. Look
before you leap.

Hope this helps
Lloyd Sheen
 
G

Guest

Lloyd,

Did you measure these times with your programs running inside the IDE, or
did you compile the code and measure the times from the compiled EXEs?

Kerry Moorman
 
L

Lloyd Sheen

Kerry Moorman said:
Lloyd,

Did you measure these times with your programs running inside the IDE, or
did you compile the code and measure the times from the compiled EXEs?

Kerry Moorman


Tried in IDE. Just tried as exe and numbers come down 1816290 to 19350.

Now that is strange that one drops and the other increases. Even with the
diff the ration is still 94 to 1.

Lloyd Sheen
 
L

Lloyd Sheen

Kerry Moorman said:
Lloyd,

Did you measure these times with your programs running inside the IDE, or
did you compile the code and measure the times from the compiled EXEs?

Kerry Moorman

Rebuilt as release and the numbers are almost identical.

Lloyd Sheen
 
P

Patrice

And the conclusion would be ?

Another option would be to use the "Is" keyword (don't know this is
implemented).

IMO using try/catch in such a situation is anyway a bad idea (is this what
the thread suggested ?)...
 
L

Lloyd Sheen

Patrice said:
And the conclusion would be ?

Another option would be to use the "Is" keyword (don't know this is
implemented).

IMO using try/catch in such a situation is anyway a bad idea (is this what
the thread suggested ?)...

Sorry can't remember exactly what the "conclusions" were but I just wanted
to do a quantitative look at the options.

LS
 
G

Guest

Have you considered using TryCast? I would be interested in seeing how it
compared in your time trials.
 
T

Tom Shelton

I noticed a thread a few days ago about the use of Try.. Catch versus
testing variables etc and had in my mind to test exactly what the impact
was. Its a mind boggler.

I created a small windows app that executed two subroutines.

The first simply created an object which does not implement an interface and
attempts to assign that object to an variable of the interface type. This
is done in a try ... catch block.

Private Sub UseTryCatch()
Dim inter As Tester
Dim obj As New WithNoInterface
starttime = Now.Ticks
For i As Integer = 0 To cnt
Try
inter = obj
Catch et As InvalidCastException
Dim iii As Integer = 1
Catch ex As Exception
Dim ii As Integer = 1
End Try
Next
endtime = Now.Ticks
Dim interv As Long
interv = endtime - starttime
Me.TimeCatch.Text = interv.ToString
End Sub

The second creates the same object but uses reflection to test if the object
supports the interface and if so then the assignment would take place.

Private Sub UseReflection()
Dim inter As Tester
Dim obj As New WithNoInterface
starttime = Now.Ticks
For i As Integer = 0 To cnt
Dim typ As Type = obj.GetType
If typ.GetInterface("Tester") IsNot Nothing Then
inter = obj
End If
Next
endtime = Now.Ticks
Dim interv As Long
interv = endtime - starttime
Me.TimeReflection.Text = interv.ToString
End Sub

The results of this test were that the try .. catch took 101087280 ticks
(about 5 seconds on a dual 3.0 G).

The reflection test took 9765 ticks (too fast to determine in my old brain).

The testing before trying was 10352 times faster. I would think that would
put to rest any questions as to the best method of capturing errors. Look
before you leap.

Hope this helps
Lloyd Sheen

If some one suggested using Try...Catch in this manner, then they are
insane :) Try...Catch should be used to handle EXCEPTIONAL
circumstances, not for flow control. Having a Try...Catch doesn't
slow down your program (at least not signifcantly), but thrown
exceptions do. There is a lot of work that goes on in building an
exception object (stack walks, interegating api calls, etc).
 
S

Stephany Young

This is exactly the reason that TryCast() was introduced.

I take it from your numbers that you only exceuted 1 iteration of the loop.
What happens if you execute 1 million or more iterations?

Seeing as Ticks are 'too fast for your old brain' to deal with, convert the
result up to a more meaningful unit. 99.9 recurring % of humans cannot
visualize 100 nanoseconds, but we can quite easily visualize seconds and
even milliseconds and microseconds.

Try this variation on your test and you will see the 'power' of TryCast().

Private Interface Tester
End Interface

Private Class WithNoInterface
End Class

Private Class WithInterface
Implements Tester
End Class

Private Sub WithOutUseTryCatch()
Dim inter As Tester = Nothing
Dim obj As New WithNoInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
inter = TryCast(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Private Sub WithOutUseReflection()
Dim inter As Tester = Nothing
Dim obj As New WithNoInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
If obj.GetType().GetInterface("Tester") IsNot Nothing Then inter =
CType(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Private Sub WithUseTryCatch()
Dim inter As Tester = Nothing
Dim obj As New WithInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
inter = TryCast(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Private Sub WithUseReflection()
Dim inter As Tester = Nothing
Dim obj As New WithInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
If obj.GetType().GetInterface("Tester") IsNot Nothing Then inter =
CType(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub
 
L

Lloyd Sheen

Stephany Young said:
This is exactly the reason that TryCast() was introduced.

I take it from your numbers that you only exceuted 1 iteration of the
loop. What happens if you execute 1 million or more iterations?

Seeing as Ticks are 'too fast for your old brain' to deal with, convert
the result up to a more meaningful unit. 99.9 recurring % of humans cannot
visualize 100 nanoseconds, but we can quite easily visualize seconds and
even milliseconds and microseconds.

Try this variation on your test and you will see the 'power' of TryCast().

Private Interface Tester
End Interface

Private Class WithNoInterface
End Class

Private Class WithInterface
Implements Tester
End Class

Private Sub WithOutUseTryCatch()
Dim inter As Tester = Nothing
Dim obj As New WithNoInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
inter = TryCast(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Private Sub WithOutUseReflection()
Dim inter As Tester = Nothing
Dim obj As New WithNoInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
If obj.GetType().GetInterface("Tester") IsNot Nothing Then inter =
CType(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Private Sub WithUseTryCatch()
Dim inter As Tester = Nothing
Dim obj As New WithInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
inter = TryCast(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Private Sub WithUseReflection()
Dim inter As Tester = Nothing
Dim obj As New WithInterface
Dim _st As Stopwatch = Stopwatch.StartNew
For i As Integer = 1 To 1000000
If obj.GetType().GetInterface("Tester") IsNot Nothing Then inter =
CType(obj, Tester)
Next
Console.WriteLine("{0:#0.0000000000}", _st.ElapsedTicks /
Stopwatch.Frequency)
Console.WriteLine(inter Is Nothing)
Console.WriteLine()
End Sub

Check out the for loop that will show the number of iterations. Even my old
brain can see that and relative times are as valid a measure as any since
everyone will have slightly different amount of memory, CPU etc.

A tick is a tick.

LS
 
P

Patrice

Ok but keep in mind that this is unlikely where your application would spent
most of its time. So unless you are doing really this a very hight number
of time I would choose clarity over (so called IMO)performance by doing
something such :

If TypeOf ThisObject Is IMyInterface Then
' Blah
Else
' Do something else
End If

that clearly express what I wan't to do...

Keep in mind that comparing times doesn't really mean anything if you don't
check also the absolute numbers and that making something that last 1 s 100
times faster won't get as much benefit as making something that last 10 s
only two times faster...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top