Dan McClain
Dan McClain

Reputation: 11920

What is fastest: (int), Convert.ToInt32(x) or Int32.Parse(x)?

Which of the following code is fastest/best practice for converting some object x?

int myInt = (int)x;

or

int myInt = Convert.ToInt32(x);

or

int myInt = Int32.Parse(x);

or in the case of a string 's'

int myInt;
Int32.TryParse(s, out myInt);

I'm curious on which performs the fastest for datatypes which have a method in Convert, not just ints. I just used int as an example.

Edit: This case arose from getting information back from a datatable. Will (int) still work the fastest?

From some testing, when object x =123123123, int performs the fastest, like many have said. When x is a string, Parse runs the fastest (note: cast throws an exception). What I am really curious is how they run when the value is being retrieved in the following way:

foreach(DataRow row in someTable.Rows)
{
    myInt = (int)row["some int value"];
    myInt2 = Int.Parse(row["some int value"]);
    myInt2 = Convert.ToInt32(row["some int value"]);
}

Upvotes: 49

Views: 38092

Answers (15)

Eric Cosky
Eric Cosky

Reputation: 574

When I have questions about performance differences between different ways of doing something specific like this, I usually make a new entry in my copy of MeasureIt, a free download from a great MSDN article from Vance Morrison. For more information please refer to the article.

By adding a simple bit of code to MeasureIt, I get the results below which compare the actual timings of the various methods of converting to int. Note the cast from string to int will throw an exception and isn't valid, so I just added the permutations that made sense to me.

 
Name                                                Median   Mean     StdDev   Min      Max    Samples       
IntCasts: Copy [count=1000 scale=10.0]              0.054    0.060    0.014    0.054    0.101    10       
IntCasts: Cast Int [count=1000 scale=10.0]          0.059    0.060    0.007    0.054    0.080    10       
IntCasts: Cast Object [count=1000 scale=10.0]       0.097    0.100    0.008    0.097    0.122    10       
IntCasts: int.Parse [count=1000 scale=10.0]         2.721    3.169    0.850    2.687    5.473    10       
IntCasts: Convert.ToInt32 [count=1000 scale=10.0]   3.221    3.258    0.067    3.219    3.418    10     


To find the best performance for the various types you are interested in, just extend the code below, which is literally all I had to add to MeasureIt to generate the above table.

static unsafe public void MeasureIntCasts()
{
    int result;
    int intInput = 1234;
    object objInput = 1234;
    string strInput = "1234";

    timer1000.Measure("Copy", 10, delegate
    {
        result = intInput;
    });
    timer1000.Measure("Cast Object", 10, delegate
    {
        result = (int)objInput;
    });

    timer1000.Measure("int.Parse", 10, delegate
    {
        result = int.Parse(strInput);
    });

    timer1000.Measure("Convert.ToInt32", 10, delegate
    {
        result = Convert.ToInt32(strInput);
    });
}

Upvotes: 13

demoncodemonkey
demoncodemonkey

Reputation: 11957

Why don't you just try it a couple of thousand times?

(this goes for all "What is fastest:" questions)


Hmmm, lots of downvotes over the years... I guess I should expand on this answer.

The above statement was made with a degree of flippancy in my youth, however I still agree with its sentiment. It is not worthwhile spending time creating a SO question asking others what they think is faster out of two or three operations that take less than 1ms each.

The fact that one might take a cycle or two longer than the other will almost certainly be negligible in day-to-day usage. And if you ever notice a performance problem in your application when you are converting millions of objects to ints, that's the point where you can profile the actual code, and you'll easily be able to test whether the int conversion is actually the bottleneck.

And whereas today it's the object-int converter, tomorrow maybe you'll think your object-DateTime converter is taking a long time. Would you create another SO question to find out what's the fastest method?

As for your situation (no doubt long since resolved by now), as mentioned in a comment, you are querying a database, so object-int conversion is the least of your worries. If I was you I would use any of the conversion methods you mentioned. If a problem arises I would isolate the call, using a profiler or logging. Then when I notice that object-int conversion is being done a million times and the total time taken by that conversion seems relatively high, I would change to using a different conversion method and re-profile. Pick the conversion method that takes the least time. You could even test this in a separate solution, or even LINQPad, or Powershell etc.

Upvotes: 21

user3810900
user3810900

Reputation:

Someone's already done the benchmarking. Here are the results. The fastest way if you know what you're converting will always be a valid int, is to use the following method (which a few people have answered above) :

int value = 0;
for (int i = 0; i < str.Length; i++)
{
    value = value * 10 + (str[i] - '0');
}

Other techniques that were benchmarked were:

  • Convert.ToInt32
  • Int32.TryParse
  • int.Parse

Upvotes: 1

pet
pet

Reputation: 11

this is not true. The fast conversion is direct cast:

int i = (int) stringData;

watch.Elapsed = {00:00:00.1732388}
watch2.Elapsed= {00:00:00.0878196}


 // Mesary start
                Stopwatch watch = new Stopwatch();

                watch.Start();
                for (int f = 1; f < 1000000; f++)
                {
                    item.Count = FastInt32.IntParseFast(dt.Rows[i]["TopCount"]);
                }   // Execute the task to be timed
                watch.Stop();

                Console.WriteLine("Elapsed: {0}", watch.Elapsed);
                Console.WriteLine("In milliseconds: {0}", watch.ElapsedMilliseconds);
                Console.WriteLine("In timer ticks: {0}", watch.ElapsedTicks);
                // Mesary end


                // Mesary start
                Stopwatch watch2 = new Stopwatch();

                watch2.Start();
                for (int n = 1; n < 1000000; n++)
                {
                    item.Count = (int)(dt.Rows[i]["TopCount"]);
                }   // Execute the task to be timed
                watch2.Stop();

                Console.WriteLine("Elapsed: {0}", watch2.Elapsed);
                Console.WriteLine("In milliseconds: {0}", watch2.ElapsedMilliseconds);
                Console.WriteLine("In timer ticks: {0}", watch2.ElapsedTicks);
                // Mesary end

Upvotes: 1

GriehmForTheWin
GriehmForTheWin

Reputation: 1

foreach(DataRow row in someTable.Rows)
{
    myInt = (int)row["some int value"];
    myInt2 = Int.Parse(row["some int value"]);
    myInt2 = Convert.ToInt32(row["some int value"]);
}

For this example, if the value coming from the table is indeed an int value, or comparable database value, then using the

myInt = (int)row["some int value"];

would be the most efficient, and hence the 'fastest' becuase the

row["some int value"];

will be a value-type int instance boxed inside an reference-type object instance, so using the explicit type cast will be the quickest becuase as other people said it is an operation not a function call, thereby reducing the cpu operations required. A call to a converion or parse method would require extra cpu operations and hence not be as 'fast'.

Upvotes: 0

Janosch
Janosch

Reputation: 1244

Extending the test of Eric Cosky by alternatives from Sam Allen, i found that if you know that your string is a valid integer, then parsing it by yourself is much faster.

I extended the test by the following cases:

    timer1000.Measure("IntParseFast", 10, delegate
    {
        result = Misc.IntParseFast(strInput);
    });

    timer1000.Measure("IntParseUnsafe", 10, delegate
    {
        result = Misc.IntParseUnsafe(strInput);
    });

With the following implementations:

public static int IntParseFast(string value)
{
    int result = 0;
    int length = value.Length;
    for (int i = 0; i < length; i++)
    {
        result = 10 * result + (value[i] - 48);
    }
    return result;
}

public unsafe static int IntParseUnsafe(string value)
{
    int result = 0;
    fixed (char* v = value)
    {
        char* str = v;
        while (*str != '\0')
        {
            result = 10 * result + (*str - 48);
            str++;
        }
    }
    return result;
}

I get the following results:

IntCaint.Parse                5,495
IntCaConvert.ToInt32          5,653
IntCaIntParseFast             1,154
IntCaIntParseUnsafe           1,245

Upvotes: 3

fractos
fractos

Reputation: 31

When optimising a bound data grid in .Net 2, I found almost half the time was spent in various object's ToString() methods that were then used as the inputs of Convert operations. By isolating these cases and by casting to the correct type where possible (since they were rows taken out of a database and the types could be relied upon) this caused a massive increase in speed of that data binding operation.

So, if you know the type of the thing up front and you'll hit the piece of code enough times, it's worth the effort to cast it directly instead of converting where necessary.

Upvotes: 2

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

Fastest != Best Practice!

For example, (int) is almost certainly the fastest because it's an operator rather than a function call, but it will only work in certain situations.

The best practice is to use the most readable code that won't negatively impact your performance, and 99 times out of 100 an integer conversion isn't driving your app's performance. If it is, use the most appropriate, narrowest conversion you can. Sometimes that's (int). Sometimes it's TryParse(). Sometimes it's Convert.ToInt32().

Upvotes: 33

dr. evil
dr. evil

Reputation: 27265

If you know that the data is definitely int then int myInt = (int)x; should be the fastest option. Otherwise TryParse will help you to get it right without the slowness of exceptions.

BTW :

(int) only unboxes therefore faster,

(int) IL =

  .locals init (
        [0] object x,
        [1] int32 Y)
    L_0000: ldc.i4.1 
    L_0001: box int32
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: unbox int32
    L_000d: ldobj int32
    L_0012: stloc.1 
    L_0013: ret 

Convert.Toint32=

.locals init (
        [0] object x,
        [1] int32 Y)
    L_0000: ldc.i4.1 
    L_0001: box int32
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
    L_000d: call int32 [mscorlib]System.Convert::ToInt32(object)
    L_0012: stloc.1 
    L_0013: ret 

Upvotes: 19

nothrow
nothrow

Reputation: 16168

(int) conversion on string won't work, so I dont test it. Convert.ToInt32 reflects as testing the value to null and THEN calling int.Parse, so should in general tend to be slower than int.Parse().

Upvotes: 0

Keith
Keith

Reputation: 155622

It depends on what you expect x to be

If x is a boxed int then (int)x is quickest.

If x is a string but is definitely a valid number then int.Parse(x) is best

If x is a string but it might not be valid then int.TryParse(x) is far quicker than a try-catch block.

The difference between Parse and TryParse is negligible in all but the very largest loops.

If you don't know what x is (maybe a string or a boxed int) then Convert.ToInt32(x) is best.

These generalised rules are also true for all value types with static Parse and TryParse methods.

Upvotes: 87

dan-gph
dan-gph

Reputation: 16899

If you had the need for the extra speed, it would be easy to test the different the different options. Since you aren't testing them, you mustn't need them. Don't waste your time with pointless micro-optimizations!

Upvotes: 0

Matthias Meid
Matthias Meid

Reputation: 12513

Not sure about performance, but these methods aren't the same at all. Both Parse and TryParse work with string, the String representation of an object is parsed (see MSDN).

Converts the string representation of a number to its 32-bit signed integer equivalent.

Not sure about casting and the Convert class, but cast is only for objects that are already integers in fact but not strongly typed.

Matthias

Upvotes: 0

GateKiller
GateKiller

Reputation: 75869

In the end, they all end up calling:

System.Number.ParseInt32(string s, NumberStyles style, NumberFormatInfo info);

So in summary, there will be no difference what so ever.

Have a look in .Net Reflector to see this.

Upvotes: -6

Surgical Coder
Surgical Coder

Reputation: 1084

Best practice would be TryParse, and seeing the result of that, if it worked - otherwise you could get exceptions

Upvotes: 6

Related Questions