Resume Exception After Handling Exception in C#

B

beginner

Hello,

We are writing a performance critical application. As a result, we use
Array instead of List or any other more sophisticated container types
to store temporary data. However, the array type is of fixed length,
and therefore there is a chance for the index to be out of range. I
expect this to happen once every a hundred times of execution and when
this happens, I'd like to create a bigger array. To prevent the bounds
from being checked every time, I am thinking of the following code (in
sketch):

int [] l= new int[100]; .//temp variable
.....
try
{

int count=0;
while(...)
{
...
l[count++]=f(...); //
....
l[count*2+1]=f(...); //multiple places that put stuff into the
array
}

}
catch(OutOfRange e)
{
//create a bigger array
l2=new int[count*2+100];
//copy partial results from old array to new array
...
//replace old array
l=l2
resume execution right after the exception was thrown
}

But I don't think there is a way in C# to support this pattern.

I think this is a really useful pattern, as it is way more efficient
to deal with such conditions that happen once in a million times.

Thanks,
Geoffrey
 
M

Marc Gravell

But I don't think there is a way in C# to support this pattern.
Correct; there is no resume
I think this is a really useful pattern, as it is way more efficient
to deal with such conditions that happen once in a million times.

Are you so sure? Have you times it both ways? Since the base-libraries
use mainly bounds-checking, I'm guessing that it isn't as slow as you
think. Of course, exceptions aren't as slow as people think, either...
Of course, the cheapest option is to check your length ahead of time
(outside of any loop).

Marc
 
N

Nicholas Paldino [.NET/C# MVP]

To add what Marc says, I don't know that not using an array over a
List<int> is going to be faster here either. What you should be doing is
pre-allocating what you think you will use (or over, if you have to
approximate) and you should get pretty even performance.

Of course, the only way to test this is to try.
 
J

Jon Skeet [C# MVP]

I think this is a really useful pattern, as it is way more efficient
to deal with such conditions that happen once in a million times.

Not only do I doubt that the performance is likely to be significantly
improved (and there's a big difference between "once in a million" and
the "once in a hundred" you originally state) - there's a massive cost
in readability.

Using exceptions like this is a really, really bad idea. From a
maintenance point of view, it is absolutely horrible. This isn't the
way to get fast code. You should profile the code and attack very
specific bottlenecks, rather than bending your code out of shape like
this without solid performance figures behind you.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

That is the kind fo programming that should not appear in a performance
critical app. It create uncertainly
It's MUCH better if you use a List<T> with enough space to accomodate the
number of items you are expecting.

You will get the same functionality than by using the array and you avoid
creating an exception.
 
B

beginner

Correct; there is no resume


Are you so sure? Have you times it both ways? Since the base-libraries
use mainly bounds-checking, I'm guessing that it isn't as slow as you
think. Of course, exceptions aren't as slow as people think, either...
Of course, the cheapest option is to check your length ahead of time
(outside of any loop).

Marc

Unfortunately checking the Length beforehand is impossible as I only
know the ballpark of the number of records I have to process and there
could be big outliers.

You are probably right. In this case, I might be able to banking on
the smartness of the optimizer. If I check the bounds explicitly in
the code, the JIT might not generate code that implicitly does so and
throws exceptions.

But this is still a useful pattern in dealing with things like
numerical computations, which is another situation I am trying to use
this pattern. It is cheaper to handle rare bad situations when it
actually happens. Without the 'resume' mechanism, I will have to redo
the whole function when some exception happens. With the resume, I can
redo at much finer granuality.
 
L

Lucas Eagleton

Hi,

I see a lot of people dislike this concept, but perhaps I have something
that may help if you want to go down the track of using arrays etc.
You could take out the count2 stuff if it was only one item added per
execution of the loop.

int currentmax=100;
int count=0;
int count2=0; // used to keep a track of the actual number of items in the
array.
int[] l = new int[currentmax];
while (...)
{
if (count2 + 'num of items added each time' > currentmax) {
currentmax += 100;
// recreate array with new currentmax size.
}

l[count++]=f(...);
count2++;

l[count*2+1]=f(...);
count2++;
}

- Lucas.
 
B

Ben Voigt [C++ MVP]

beginner said:
Hello,

We are writing a performance critical application. As a result, we use
Array instead of List or any other more sophisticated container types
to store temporary data. However, the array type is of fixed length,
and therefore there is a chance for the index to be out of range. I
expect this to happen once every a hundred times of execution and when
this happens, I'd like to create a bigger array. To prevent the bounds
from being checked every time, I am thinking of the following code (in
sketch):

int [] l= new int[100]; .//temp variable
....
try
{

int count=0;
while(...)
{
...
l[count++]=f(...); //
....
l[count*2+1]=f(...); //multiple places that put stuff into the
array
}

}
catch(OutOfRange e)
{
//create a bigger array
l2=new int[count*2+100];
//copy partial results from old array to new array
...
//replace old array
l=l2
resume execution right after the exception was thrown
}

But I don't think there is a way in C# to support this pattern.

I think this is a really useful pattern, as it is way more efficient
to deal with such conditions that happen once in a million times.

Trouble is, the OutOfRange exception isn't thrown using hardware support
(access violation exception using vectored handlers) where you could
actually see a performance gain. Instead, the compiler has to insert the
exact check you are trying to avoid. So check it yourself, then the
optimizer should remove the redundant checks and all the exception baggage.

It would be a different story if using VirtualAlloc to set up your buffer,
so that out of range accesses hit a guard region and cause a page fault.
But in .NET you'd just be accessing the next object on the gc heap, not
faulting.
 
B

Ben Voigt [C++ MVP]

Peter Bromberg said:
I agree with the other responders. At first blush, you seem to be using
exceptions for handling business logic. That's not what they are for. The
idea is to AVOID having exceptions in the first place.

The idea is valid, only doesn't work with .NET arrays. Of course it's an
implementation detail that should be well encapsulated from the user.

Exceptions are designed for implementing the unusual case without loading
down the fast path.

For example, the stack (for parameter passing) uses exactly the technique
the OP is discussing.
-- Peter
Site: http://www.eggheadcafe.com
UnBlog: http://petesbloggerama.blogspot.com
MetaFinder: http://www.blogmetafinder.com


beginner said:
Hello,

We are writing a performance critical application. As a result, we use
Array instead of List or any other more sophisticated container types
to store temporary data. However, the array type is of fixed length,
and therefore there is a chance for the index to be out of range. I
expect this to happen once every a hundred times of execution and when
this happens, I'd like to create a bigger array. To prevent the bounds
from being checked every time, I am thinking of the following code (in
sketch):

int [] l= new int[100]; .//temp variable
.....
try
{

int count=0;
while(...)
{
...
l[count++]=f(...); //
....
l[count*2+1]=f(...); //multiple places that put stuff into the
array
}

}
catch(OutOfRange e)
{
//create a bigger array
l2=new int[count*2+100];
//copy partial results from old array to new array
...
//replace old array
l=l2
resume execution right after the exception was thrown
}

But I don't think there is a way in C# to support this pattern.

I think this is a really useful pattern, as it is way more efficient
to deal with such conditions that happen once in a million times.

Thanks,
Geoffrey
 

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