比较两个数字,哪种方法性能最佳?

3

我需要比较很多整数值是否相等。

哪种方法最快?

A)

int a1 = 12345;
int a2 = 54321;
if(a1 == a2)
{
   //do something.
}

B)
int a1 = 12345;
int a2 = 54321;
if( (a1 ^ a2) == 0 )
{
   //do something.
}

6
我会说第一个(也许是因为如果第二个更快,那么第一个就会在内部实现)。 - devoured elysium
1
你想每秒实际运行这个比较多少次?这些数字来自哪里:文件、数据库?你将它们存储在什么类型的集合中?在大多数情况下,优化这样的语句是没有意义的,因为周围所有其他操作都比它慢得多。 - Steven
4个回答

9

我怀疑第一个选项实际上更快。毕竟,比较两个整数是否相等并不是一项罕见的操作,所以我想它应该得到了很好的支持 :) 然而,更重要的是它更加易读

在我看来,将整数进行比较以检查它们是否相等几乎不可能成为瓶颈。如果你真的觉得这是问题,那么请在尽可能真实的情况下对你的代码进行基准测试,然后尝试各种更改(例如异或、减法等)并重新测量。但请确保在花费时间远离最明显、简单、易读的代码之前,确实有需要解决的问题。


我已经验证了这一点,并在我的答案中描述。谢谢回答。 - Yuriy

5
唯一回答这样的问题的方法是在你特定的应用和环境中进行测量。但首先要做的是不要担心它。在C#中,你很可能不会遇到这个问题。如果你处于某种奇怪的性能边缘情况,你确实比MS工具团队更了解如何比较整数,那么你应该写汇编语言。个人而言,我无法想象一个场景,在一个紧密循环中比较两个整数会支配你的时间 - 循环和分支开销将与比较成本相似或更大,即使这个大块数据神奇地出现在CPU缓存中,也没有任何分页或内存I/O成本。对于像比较(以及设置为零和乘以常量二次幂)这样的操作,Rococo替代品在最好的商业工具链中已经不适用了(烂掉的嵌入式C编译器可能仍然需要它们),已经有将近20年的时间了。是时候停止考虑它们了。

我已经验证过了,并在我的回答中进行了描述。感谢您的回答。 - Yuriy

3

我已经编写了一些代码来验证这个问题。

static void Main( string[] args )
{
  int a1 = 123456;
  int a2 = 654321;
  int a3;

  var t = new System.Diagnostics.Stopwatch();
  t.Start();
  for ( int i = 0; i < int.MaxValue; i++ )
  {
    if ( a1 == a2 )
    {
      a3 = a1 + a2;
    }
  }
  t.Stop();

  Console.WriteLine( t.ElapsedMilliseconds );

  t.Reset();

  t.Start();
  for ( int i = 0; i < int.MaxValue; i++ )
  {
    if ( ( a1 ^ a2 ) == 0 )
    {
      a3 = a1 + a2;
    }
  }
  t.Stop();

  Console.WriteLine( t.ElapsedMilliseconds );

  Console.ReadKey();
}

结果如下:
对于第一个方法,用时6275毫秒
对于第二个方法,用时6277毫秒
看起来这两种方法的效果相同。
感谢您的回答。

1
第一个。因为它们都执行比较操作(==),但第二个使用了额外的异或操作。

1
你有测量过差异吗?你确定这是事实还是在做出假设? - Binary Worrier
我没有测量它,因为很难测量。我编写了一个简单的测试,在每次启动时都显示不同的结果,因为 CPU 中存在进程并发。我认为查看 MSIL 反汇编会更有效,而不是测量。 - Bogdan Verbenets
2
如果你无法轻松地测量差异,那么肯定没有任何重要的差异,为什么要偏爱一种方法而不是另一种方法。即使是 MSIL 在编译时也会被优化,你还需要查看编译器以了解它发出的字节码。在性能方面,这两者之间没有选择余地。在可读性方面,有很大的差异,提问者应该选择第一个。 - Binary Worrier
如果你无法轻松地测量差异,那么肯定没有任何重要的差异——是的,我同意这个观点。 - Bogdan Verbenets
结果会取决于Jitter版本、CPU类型、前后代码等因素,但最可能的情况是它们将执行相同。 - H H
我已经验证过了,并在我的回答中进行了描述。感谢您的回答。 - Yuriy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接