-->

Wednesday, 29 February 2012

We’re Hiring

Open Projects is a software house based in Nottingham UK, specialising in software for the newspaper/magazine circulation industry.  There are vacancies for two new people to join the team.

  • A developer with skills in VB.Net, C#, ASP and SQL to work on Windows, web and mobile solutions.
  • An IT Support professional to handle second line support and to make sure none of the servers are on fire.

For more details and how to apply, please go to the Open Projects Careers page.

Monday, 6 June 2011

How to Convert Strings to Integers in Visual Basic

While recently reviewing a piece of code, I managed to spot three different methods being used for converting values stored in objects or strings into Integers.  This is where Visual Basic takes the record for having the most methods for performing the same operation.  Thinking about it I realised that I could name six different ways of converting strings to integers in Visual Basic…

This post is a "back to basics" investigation into which way is best to convert to an Integer.

Meet the methods:

CInt, CType, Int, Convert.Int32, Integer.Parse, & Integer.TryParse

CInt, CType and Int belong to the Microsoft.VisualBasic namespace.  Convert.Int32, Integer.Parse and Integer.TryParse are from the main body of the .Net Framework.

To find the best way of converting a string to an integer I have run each of the methods through a series of tests; the speed of each method, its ability to round number, handle Nothing (null) and completely invalid values.

 

Test 1 – Speed

In order to find the fastest method of converting a string to an integer each method was put through its paces converting the string “100” into an integer. To be able to see the difference in timings the operation was performed 100 million times. Each test run was carried out multiple times to achieve an average timing. Each batch of test runs were performed against three different version of the .Net Frameworks, 2.0, 3.5 and 4.0.

clip_image002

(These timings are specific to my PC and should only be used for comparison with each other)

The fastest method for .Net 2.0 and .Net 3.5 is Integer.Parse at 13.12 seconds and 13.23 seconds respectively, but is overtaken for .Net 4.0 by Integer.TryParse at 13.19 seconds.

It is nice to know that using the TryParse method does not mean you are getting the performance hit you might imagine for the extra checking. (During testing a Boolean variable was being set to the result of the parse test).

CInt, CType and Int performed badly in comparison to the other methods. This is conceivably due to these methods being there for backwards compatibility with old VB6 code, although as you will see in the next few tests they do more than the other methods.

 

Test 2 - Rounding

Sometime it is desirable to round values that are not whole numbers into integers, for this test each method was passed “0.5” and “0.6” to determine if it could successfully convert the value to an integer, and whether it would round the number up or down.

Method

0.5

0.6

CInt

0

1

Convert.ToInt32

Exception

Exception

CType

0

1

Int

0

0

Integer.Parse

Exception

Exception

Integer.TryParse

Failed

Failed

Only the Microsoft.VisualBasic methods handled the test, the others threw exceptions apart from Integer.TryParse which, being designed for this scenario, reported a failure.

Also it is interesting to note that Int will always returns the integer portion of the number, and so always rounds down for positive numbers and up for negative numbers. In researching this post I came across, if you can believe it, a seventh method of converting a string to an integer called Fix, which is very similar to Int but handles negative numbers differently.

 

Test 3 – Nothing (null)

These are the results from attempting to convert a string set to Nothing into an integer.

Method

Result

CInt

0

Convert.ToInt32

0

CType

0

Int

ArgumentNullException

Integer.Parse

ArgumentNullException

Integer.TryParse

Failed (0)

Interestingly the first three methods consider Nothing to be the same as zero, while once again Integer.TryParse rejects the value.

 

Test 4 – Invalid Integer

Strings can of course contain text as well as numbers, the following results are when attempting to convert the string “abc” into an integer.

Method

Result

CInt

InvalidCastException

Convert.ToInt32

FormatException

CType

InvalidCastException

Int

InvalidCastException

Integer.Parse

FormatException

Integer.TryParse

Failed

Well I think from these results that it is fairly obvious that the language designers do not think it is a good idea to be able to pass any old string into an integer conversion. I agree, I would prefer my applications to fail fast rather than perhaps silently returns zeros when passed random text (as with Nothing above).

 

Overall Results

So which is best and why? Well it all comes down to how you are going to be using the function and what sort of data you want the function to handle.

Unless you want the specific rounding abilities of Int then I can’t see any reason to ever use it. It performed badly against every test, making it the worst overall.

If you need speed then you should ignore the Microsoft.VisualBasic methods, as they are at least twice as slow as the others.

If you need to handle general rounding then CInt and CType are the only functions for you.

If the data being presented for conversion may not be an integer, then use Integer.TryParse to successfully determine this without throwing an exception, in the fastest time. The only catch with this method is that you need to remember to handle the function passing back a failure result.

Finally if you want the speed without the extra coding complexity that goes with handling the result from Integer.TryParse, the Integer.Parse looks best.

Friday, 13 May 2011

Creating Deadlocks

I wrote a post a while ago on how to handle database deadlocks in your code, where I described how to programmatically detect and handle your code being chosen as the deadlock victim by SQL Server.
Running up against some deadlocking issues recently, I needed a way to reliably produce a deadlock so that I could test various scenarios.  I thought it might be useful to someone who needed to do the same thing, so this is what I did.

Step 1 – Create the resources to lock

To begin with we need two tables and data that we can lock.  (This is a prerequisite to actually producing the deadlock.)

create table ResourceA (DataFieldA int not null)
insert into ResourceA (DataFieldA) values (1)
create table ResourceB (DataFieldB int not null)
insert into ResourceB (DataFieldB) values (1)

Now we need a method of getting Process 1 to lock Resource A while wanting Resource B, and at the same time having Process 2 lock Resource B while wanting Resource A.

Step 2 – Process One to Lock the data
begin tran Process1
update ResourceA set DataFieldA = 2
waitfor delay '00:00:05'
update ResourceB set DataFieldB = 2
commit tran Process1

What happens here is that Process 1 locks Resource A, then while the lock is still being held there is a delay which gives us enough time to execute step 3, then Process 1 tries to get a lock on Resource B

Step 3 – Process Two to Deadlock

While Process 1 is delayed after locking Resource A, we can execute Process 2 which will lock Resource B before Process 1 can get to it.

begin tran Process2
update ResourceB set DataFieldB = 3
update ResourceA set DataFieldA = 3
commit tran Process2

This will cause a deadlock and result in one of our two processes being rolled back.  The actual process that is chosen as the deadlock victim, will be selected based on which one SQL Server determines is the easiest to rollback.
So we have got to the point where we can create a deadlock, but we need a way of picking the process that we want to be rolled back.  This is achieved by setting the deadlock priority on Process 1, to specify that it should not be chosen.

SET DEADLOCK_PRIORITY HIGH
begin tran Process1
update ResourceA set DataFieldA = 2
waitfor delay '00:00:05'
update ResourceB set DataFieldB = 2
commit tran Process1
 
Now Process 2 will consistently be chosen as the deadlock victim, giving you a reliable way of creating deadlocks in your database.