我有一个用c#编写的程序,其中有一些int和字符串之间的比较。
因此,出于性能原因,我想知道哪个更有效?
如果我们有:
int a = 5;
string b = "5";
if(a == int.Parse(b)) { }
OR
if(a.ToString() == b) { }
答案 0 :(得分:8)
我实际上是使用一些示例和定时循环来描述它。事实证明,小整数的Parse胜利,而大型的ToString胜利。这种差异是如此之小,不应该引起关注,正如其他人所提到的那样,通过考虑字符串根本不代表整数的情况,你可能会做出更好的选择。
编辑:对于有兴趣的人,这里有来源,快速'n'脏:
using System;
using System.Diagnostics;
namespace CompareTest
{
static class Program
{
static void Main(string[] args)
{
int iterations = 10000000;
int a = 5;
string b = "5";
Stopwatch toStringStopwatch = new Stopwatch();
toStringStopwatch.Start();
for (int i = 0; i < iterations; i++) {
bool dummyState = a.ToString() == b;
}
toStringStopwatch.Stop();
Stopwatch parseStopwatch = new Stopwatch();
parseStopwatch.Start();
for (int i = 0; i < iterations; i++) {
bool dummyState = a == int.Parse(b);
}
parseStopwatch.Stop();
Console.WriteLine("ToString(): {0}", toStringStopwatch.Elapsed);
Console.WriteLine("Parse(): {0}", parseStopwatch.Elapsed);
Console.ReadLine();
}
}
}
答案 1 :(得分:5)
一些评论提到运行一个分析工具来证明哪个具有更好的性能。
这是好的,但检查特定语句性能的最简单方法是将它们放在循环中并使用Stopwatch类。
杰夫阿特伍德在this question中询问如何使这种时机变得更简单。在那个问题和答案中,您还会找到一些很好的代码示例和背景细节。
这是一个非常简单的工作示例:
System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();
int a = 5;
string b = "5";
sw.Start();
for (int i=0;i<1000000;i++)
{
if(a == int.Parse(b))
{
}
}
sw.Stop();
Console.WriteLine("a == int.Parse(b) milliseconds: " + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i=0;i<1000000;i++)
{
if(a.ToString() == b)
{
}
}
sw.Stop();
Console.WriteLine("a.ToString() == b milliseconds: " + sw.ElapsedMilliseconds);
在我的电脑上输出:
a == int.Parse(b)毫秒:521
a.ToString()== b毫秒:697
所以在这个简单的场景中,int.Parse()稍快一点,但还不够真正担心。
答案 2 :(得分:4)
您的选择介于以下之间 代码清单A
int a = 5;
string b = "5";
//Assuming these two values are input received by the application at runtime
int bInt;
if (int.TryParse(b, NumberStyles.None, CultureInfo.InvariantCulture, out bInt)
&& a.Equals(bInt))
{
}
和
代码清单B
int a = 5;
string b = "5";
//Assuming these two values are input received by the application at runtime
if (string.Compare(b, a.ToString(), StringComparison.Ordinal) != -1)
{
}
我用秒表测试了这个(在所选答案中给出)并且发现代码清单A要快得多。 但是代码清单B更具可读性!
代码清单A节拍if(a == int.Parse(b))
答案 3 :(得分:3)
在内部,ToString和Parse执行以下操作:
<强>解析强>
value = 0
for each char in string
value = value * 10 + valueof(char) // i.e. '0' -> 0, '7' -> 7
<强>的ToString 强>
string=""
while value > 0
string.insert_at_front value % 10 // so that 0 -> '0' and 6 -> '6'
value /= 10
// on IA32, the % and / can be done at the same time but requires
// a 64bit source for 32bit values
ToString应该比Parse慢,因为除法通常比乘法慢。但是,上面没有考虑Parse和ToString函数在转换期间可能执行的任何开销(即生成异常,分配内存),这意味着它不是更明确的更优化。
从其他答案看,差异似乎是微不足道的,所以只要使用对你更有意义的东西。
答案 4 :(得分:2)
你已经得到了一些好的回答,但是我要补充几点。
微基准测试的一个众所周知的风险是,少量重复可能最终会测量噪音(例如,时间可能会被传入的电子邮件或IM歪斜),但是大量的重复最终可以测量垃圾收集器的性能(例如,如果您的代码不断创建和丢弃字符串)。
当我发现自己处于代码中的尴尬境地时,有时候会问自己:“在这种情况下我有什么假设或选择?我能做些什么不同的事情?”例如(只是猜测),当你写“......在int的* [sic] *和字符串之间有很多比较”时,这是否意味着你可能重复使用相同的值(例如,比较新的值)以前的价值观)? 如果是这样,你可以将每个字符串转换为int,并缓存转换后的值以供后续重用,而不必在以后再次转换它吗?
答案 5 :(得分:2)
我把我带到这里的案例是检查&#34; 5&#34; = = 5在一个开关盒中因为我总是会收到0到9之间的数字,我发现最快的方法是:
(int)b[0] == 53
所以我采取字符串的第一个字符&#34; 5&#34; (b [0])并将其转换为ACSII值,即53,然后进行比较。结果如下:
a == int.Parse(b) milliseconds: 194
a.ToString() == b milliseconds: 142
a == (int)(b[0]) milliseconds: 8
即使这是非常不寻常的情况,大规模阵列的差异是显而易见的;
switch((int)b[0])
{
case 48: Console.WriteLine("0");
break;
case 49: Console.WriteLine("1");
break;
case 50: Console.WriteLine("2");
break;
case 51: Console.WriteLine("3");
break;
case 52: Console.WriteLine("4");
break;
case 53: Console.WriteLine("5");
break;
case 54: Console.WriteLine("6");
break;
case 55: Console.WriteLine("7");
break;
case 56: Console.WriteLine("8");
break;
case 57: Console.WriteLine("9");
break;
}
为了一个良好的秩序,这里是你问我的结果:
a == int.Parse(b) milliseconds: 184
a.ToString() == b milliseconds: 135
a + 48 ==(int)b[0] milliseconds: 8
正如你所看到的那样,只添加一个添加就没有那么大的区别。
答案 6 :(得分:1)
第一种方法的数字越大。 一个。如果b不是数字,则在尝试比较之前会失败。 湾字符串一次比较长度和数字。
答案 7 :(得分:1)
我怀疑这两个电话会对你的应用程序产生重大影响,除非你真的在大规模创作。
这两种技术都在创建一个新字符串,但int.ToString()
必须执行的任务少于int.Parse().
int.ToString()
在CLR(comnumber)内部执行。 int.Parse()
使用Number.ParseInt32()
- &gt;在BCL source内完成Number.StringToNumber()
Number.ParseNumber()
- &gt; ParseNumber
。
NumberToString
执行大量检查,所以从空中猜测你会想象int.ToString()更快。正如其他人所提到的,使用StopWatch类进行适当的性能测试将是更好的方法。您将需要使用您期望的数字格式来尝试:十进制,十六进制。
您可以比较CLR用于ToString()here的C ++:查找
FCIMPL3
(用于ToString()和其他格式)在extern
中使用,由int.ToString()调用为Int32ToDecStr
调用。 var x = 5.ToString("D");
var y = 5.ToString();
用于“D”格式化程序。 C#
{{1}}
我对FCIMPL3错了,如果我是,请纠正我。
答案 8 :(得分:0)
将字符串解析为Int32需要更高的性能,并且对错误更敏感。您必须首先确保Int32.Parse成功。 您也可以使用“==”的替代方法。使用.Equals(),这更容易阅读和理解。
if(b.Equals(a))
{
}
答案 9 :(得分:0)
另外我读somwhere(MSDN)使用以下比==更快的字符串比较
StringA.ToUpperInvariant() == StringB.ToUpperInvariant()
答案 10 :(得分:0)
有许多方法可以表示与字符串相同的数字...