Reputation: 11920
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
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
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
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:
Upvotes: 1
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
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
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
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
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
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
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
Reputation: 155622
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
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
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
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
Reputation: 1084
Best practice would be TryParse, and seeing the result of that, if it worked - otherwise you could get exceptions
Upvotes: 6