哪个是快速比较:Convert.ToInt32(stringValue)== intValue或stringValue == intValue.ToString()

在开发我的应用程序时,我遇到了一些比较的东西,这里是:

string str = "12345"; int j = 12345; if (str == j.ToString()) { //do my logic } 

我以为上面的东西也可以用:

  string str = "12345"; int j = 12345; if (Convert.ToInt32(str) == j) { //do my logic } 

所以我开发了一个示例代码来测试性能,哪个更好

  var iterationCount = 1000000; var watch = new Stopwatch(); watch.Start(); string str = "12345"; int j = 12345; for (var i = 0; i < iterationCount; i++) { if (str == j.ToString()) { //do my logic } } watch.Stop(); 

第二个:

  var iterationCount = 1000000; var watch = new Stopwatch(); watch.Start(); string str = "12345"; int j = 12345; for (var i = 0; i < iterationCount; i++) { if (Convert.ToInt32(str) == j) { //do my logic } } watch.Stop(); 

在进行上述两项测试时,我发现上述测试的时间几乎相同。 我想讨论哪一个更好的方法? 还有其他方法比两个以上的方法更好吗?

你的测试存在根本缺陷。 编译器和运行时非常聪明,并且会在编译时和运行时优化代码(JIT-ing)。 在这种情况下,您每次都会执行相同的操作 ,这将由编译器发现并进行优化,因此每种方法的时序都相似。

试试这个版本(我只有.Net 2.0,因此稍有变化):

 using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace ToStringTest { class Program { const int iterationCount = 1000000; static TimeSpan Test1() { Stopwatch watch = new Stopwatch(); watch.Start(); string str = "12345"; int j = 12345; for (int i = 0; i < iterationCount; i++) { if (str == i.ToString()) { //do my logic } } watch.Stop(); return watch.Elapsed; } static TimeSpan Test2() { Stopwatch watch = new Stopwatch(); watch.Start(); string str = "12345"; int j = 12345; for (int i = 0; i < iterationCount; i++) { if (Convert.ToInt32(i) == j) { //do my logic } } watch.Stop(); return watch.Elapsed; } static void Main(string[] args) { Console.WriteLine("ToString = " + Test1().TotalMilliseconds); Console.WriteLine("Convert = " + Test2().TotalMilliseconds); } } } 

你将看到巨大的差异。 一个比另一个快两个数量级。 它真的是显而易见的。

您需要知道各种操作正在做什么才能知道哪些操作从根本上更快。

将字符串转换为int需要以下内容:

 total = 0 for each character in string total = total * 10 + value of charater 

和ToString需要:

 string = "" while value != 0 string.AddToFront value % 10 value /= 10 

对于CPU来说,乘法比分割更容易,更快。 考虑到选择具有大量乘法的算法与具有大量除法的算法,总是选择前者,因为它总是更快。

然后是比较,int-int比较很简单,将每个值加载到寄存器中并进行比较 - 几个机器指令就完成了。 两个字符串之间的比较需要一次一个地测试字符串中的每个字符 - 在您给出的示例中,它是5个字节(int可能是4个字节),这是更多的内存访问。

好 – 性能不应该是唯一重要的事情。

您应该询问是要比较实际值还是仅比较数字的表示。

采用以下示例:“00001”是否等于1? 如果您希望它使用Int.TryParse组合将字符串转换为int,然后比较它们。

根据本地设置,可能还有其他差异。 也许用户已设置格式化“1,000,000”之类的数字 – 如果您将该字符串与1000000.ToString()进行比较,结果将为false。

我更喜欢i.ToString() == str因为没有什么能保证Convert.ToInt32(str)不会失败。

是的,您将域逻辑显示为在分析循环中,因此您没有测试代码的ConvertToString版本之间的时差; 您正在测试转换的合并时间以及业务逻辑的执行。 如果您的业务逻辑很慢并占据转换时间,那么您当然会在每个版本中看到相同的时间。

现在,尽管如此,在您知道这是一个性能瓶颈之前,即使担心这一点,也需要过早优化。 特别是,如果执行域逻辑控制转换时间,则两者之间的差异永远不会重要。 因此,选择最具可读性的。

现在,关于使用哪个版本:您需要首先准确指定您正在测试的内容。 你有什么投入? “007”是否会成为输入? “007”与整数7不同吗? “1,024”是否会成为输入? 是否存在本地化问题?

如果性能几乎相同,请使用更具可读性的版本。

就个人而言,我发现.ToString()方法更容易理解,并且更不容易出现另一种方法可能存在的转换问题。

语义有点不同。 "01" == 1.ToString()false1 == Convert.ToInt32("01")

如果解析可能出错(字符串不是有效数字),那么Int32.TryParse比使用Convert.ToInt32()更快。

对于初学者来说,将int转换为字符串的第一个将不会抛出错误,如果与int进行比较的字符串不能转换为int。

如果您在批量转换为字符串时进行了大量测试,则会因转换错误而消除可能出现exception抛出的问题。 提高exception需要时间并且会减慢第二次测试的速度。

好的,我进一步向前迈进了一步并以这种方式进行测试:

  int j = 123; for (var i = 0; i < iterationCount; i++) { j.ToString(); } 

第二个:string str =“123”;

  for (var i = 0; i < iterationCount; i++) { Convert.ToInt32(str); } 

在这种情况下,我发现每次第二次表现都好一点。 就我而言,这个数字只有100000而不是10万。 你对这个测试的评论我在这篇文章中做了什么?