| 几个字符串转整数的函数,哪个执行速度快? |
via2005

常用的转换函数有Int32.Parse(numstring)、Int32.TryParse(numstring)、Convert.ToInt32(numstring),哪个的执行效率高?
微软有个测试程序,没有包含Convert.ToInt32,稍作修改,代码如下:
using System;
using System.Diagnostics;
namespace StopWatchSample
{
class OperationsTimer
{
public static void Main()
{
DisplayTimerProperties();
Console.WriteLine();
Console.WriteLine("Press the Enter key to begin:");
Console.ReadLine();
Console.WriteLine();
TimeOperations();
}
public static void DisplayTimerProperties()
{
// Display the timer frequency and resolution.
if (Stopwatch.IsHighResolution)
{
Console.WriteLine("Operations timed using the system's high-resolution performance counter.");
}
else
{
Console.WriteLine("Operations timed using the DateTime class.");
}
long frequency = Stopwatch.Frequency;
Console.WriteLine(" Timer frequency in ticks per second = {0}",
frequency);
long nanosecPerTick = (1000L*1000L*1000L) / frequency;
Console.WriteLine(" Timer is accurate within {0} nanoseconds",
nanosecPerTick);
}
private static void TimeOperations()
{
long nanosecPerTick = (1000L*1000L*1000L) / Stopwatch.Frequency;
const long numIterations = 100000;
// Define the operation title names.
String [] operationNames = {"Operation: Int32.Parse(\"0\")",
"Operation: Int32.TryParse(\"0\")",
"Operation: Int32.Parse(\"a\")",
"Operation: Int32.TryParse(\"a\")",
"Operation: Convert.ToInt32(\"0\")",
"Operation: Convert.ToInt32(\"a\")"
};
// Time four different implementations for parsing
// an integer from a string.
for (int operation = 0; operation <= 5; operation++)
{
// Define variables for operation statistics.
long numTicks = 0;
long numRollovers = 0;
long maxTicks = 0;
long minTicks = Int64.MaxValue;
int indexFastest = -1;
int indexSlowest = -1;
long milliSec = 0;
Stopwatch time10kOperations = Stopwatch.StartNew();
// Run the current operation 10001 times.
// The first execution time will be tossed
// out, since it can skew the average time.
for (int i=0; i<=numIterations; i++)
{
long ticksThisTime = 0;
int inputNum;
Stopwatch timePerParse;
switch (operation)
{
case 0:
// Parse a valid integer using
// a try-catch statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch.StartNew();
try
{
inputNum = Int32.Parse("0");
}
catch (FormatException)
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse.Stop();
ticksThisTime = timePerParse.ElapsedTicks;
break;
case 1:
// Parse a valid integer using
// the TryParse statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch.StartNew();
if (!Int32.TryParse("0", out inputNum))
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse.Stop();
ticksThisTime = timePerParse.ElapsedTicks;
break;
case 2:
// Parse an invalid value using
// a try-catch statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch.StartNew();
try
{
inputNum = Int32.Parse("a");
}
catch (FormatException)
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse.Stop();
ticksThisTime = timePerParse.ElapsedTicks;
break;
case 3:
// Parse an invalid value using
// the TryParse statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch.StartNew();
if (!Int32.TryParse("a", out inputNum))
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse.Stop();
ticksThisTime = timePerParse.ElapsedTicks;
break;
case 4:
// Parse a valid integer using
// a try-catch statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch.StartNew();
try
{
inputNum = Convert.ToInt32("0");
}
catch (FormatException)
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse.Stop();
ticksThisTime = timePerParse.ElapsedTicks;
break;
case 5:
// Parse a valid integer using
// a try-catch statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch.StartNew();
try
{
inputNum = Convert.ToInt32("a");
}
catch (FormatException)
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse.Stop();
ticksThisTime = timePerParse.ElapsedTicks;
break;
default:
break;
}
// Skip over the time for the first operation,
// just in case it caused a one-time
// performance hit.
if (i == 0)
{
time10kOperations.Reset();
time10kOperations.Start();
}
else
{
// Update operation statistics
// for iterations 1-10001.
if (maxTicks < ticksThisTime)
{
indexSlowest = i;
maxTicks = ticksThisTime;
}
if (minTicks > ticksThisTime)
{
indexFastest = i;
minTicks = ticksThisTime;
}
numTicks += ticksThisTime;
if (numTicks < ticksThisTime)
{
// Keep track of rollovers.
numRollovers ++;
}
}
}
// Display the statistics for 10000 iterations.
time10kOperations.Stop();
milliSec = time10kOperations.ElapsedMilliseconds;
Console.WriteLine();
Console.WriteLine("{0} Summary:", operationNames[operation]);
Console.WriteLine(" Slowest time: #{0}/{1} = {2} ticks",
indexSlowest, numIterations, maxTicks);
Console.WriteLine(" Fastest time: #{0}/{1} = {2} ticks",
indexFastest, numIterations, minTicks);
Console.WriteLine(" Average time: {0} ticks = {1} nanoseconds",
numTicks / numIterations,
(numTicks * nanosecPerTick) / numIterations );
Console.WriteLine(" Total time looping through {0} operations: {1} milliseconds",
numIterations, milliSec);
}
}
}
}
执行结果:
Operation: Int32.Parse("0") Summary:
Slowest time: #50002/100000 = 530910 ticks
Fastest time: #29081/100000 = 2925 ticks
Average time: 3112 ticks = 0 nanoseconds
Total time looping through 100000 operations: 198 milliseconds
Operation: Int32.TryParse("0") Summary:
Slowest time: #90323/100000 = 3195660 ticks
Fastest time: #47524/100000 = 2910 ticks
Average time: 3181 ticks = 0 nanoseconds
Total time looping through 100000 operations: 201 milliseconds
Operation: Int32.Parse("a") Summary:
Slowest time: #50191/100000 = 48579780 ticks
Fastest time: #96511/100000 = 150705 ticks
Average time: 166736 ticks = 0 nanoseconds
Total time looping through 100000 operations: 5682 milliseconds
Operation: Int32.TryParse("a") Summary:
Slowest time: #54275/100000 = 3894420 ticks
Fastest time: #41662/100000 = 2865 ticks
Average time: 3048 ticks = 0 nanoseconds
Total time looping through 100000 operations: 195 milliseconds
Operation: Convert.ToInt32("0") Summary:
Slowest time: #54110/100000 = 24327855 ticks
Fastest time: #8273/100000 = 2970 ticks
Average time: 3481 ticks = 0 nanoseconds
Total time looping through 100000 operations: 214 milliseconds
Operation: Convert.ToInt32("a") Summary:
Slowest time: #42929/100000 = 12775425 ticks
Fastest time: #56282/100000 = 154125 ticks
Average time: 167500 ticks = 0 nanoseconds
Total time looping through 100000 operations: 5704 milliseconds
可以看到,在不发生错误,确保能成功转换时,效率差不多。当转换发生错误时,由于try catch开销太大,所耗费的时间是正常值的30倍。
因此,最优的方法是Int32.TryParse(numberString, out inputNum)
