Java:为什么计算比赋值(int)更快?

标签 java performance variable-assignment

同一函数的以下 2 个版本(基本上尝试通过暴力恢复密码)不会提供相同的性能:

版本 1:

private static final char[] CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
private static final int N_CHARS = CHARS.length;
private static final int MAX_LENGTH = 8;

private static char[] recoverPassword()
{
   char word[];
   int refi, i, indexes[];

   for (int length = 1; length <= MAX_LENGTH; length++)
   {
      refi = length - 1;
      word = new char[length];
      indexes = new int[length];
      indexes[length - 1] = 1;

      while(true)
      {
         i = length - 1;
         while ((++indexes[i]) == N_CHARS)
         {
            word[i] = CHARS[indexes[i] = 0];
            if (--i < 0)
               break;
         }

         if (i < 0)
            break;

         word[i] = CHARS[indexes[i]];

         if (isValid(word))
            return word;
      }
   }
   return null;
}

版本 2:

private static final char[] CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
private static final int N_CHARS = CHARS.length;
private static final int MAX_LENGTH = 8;

private static char[] recoverPassword()
{
   char word[];
   int refi, i, indexes[];

   for (int length = 1; length <= MAX_LENGTH; length++)
   {
      refi = length - 1;
      word = new char[length];
      indexes = new int[length];
      indexes[length - 1] = 1;

      while(true)
      {
         i = refi;
         while ((++indexes[i]) == N_CHARS)
         {
            word[i] = CHARS[indexes[i] = 0];
            if (--i < 0)
               break;
         }

         if (i < 0)
            break;

         word[i] = CHARS[indexes[i]];

         if (isValid(word))
            return word;
      }
   }
   return null;
}

我希望版本 2 会更快,正如它所做的那样(这是唯一的区别):

i = refi;

...与版本 1 相比:

i = length -1;

然而,事实恰恰相反:版本 1 速度快了 3% 以上! 有人知道为什么吗?这是由于编译器做了一些优化吗?

感谢大家到目前为止的回答。 只是补充一点,目标实际上不是优化这段代码(已经相当优化了),而是更多地从编译器/CPU/架构的角度理解如何解释这种性能差异。 您的回答非常有帮助,再次感谢!

关键

最佳答案

很难在微基准测试中检查这一点,因为如果不读取生成的机器代码,您就无法确定代码是如何优化的,即使 CPU 可以做很多技巧来优化它,例如。它将 RISC 风格指令中的 x86 代码转为实际执行。

一次计算只需一个周期,CPU 最多可以同时执行三个周期。访问 L1 缓存需要 4 个周期,而访问 L2、L3、主存则需要 11、40-75、200 个周期。

在许多情况下,存储值以避免简单计算实际上会更慢。顺便说一句,使用除法和模数是相当昂贵的,在微调代码时缓存这个值是值得的。

关于Java:为什么计算比赋值(int)更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18247523/

相关文章:

java - 从字符串更改为对象名称 Java

c++ - 什么是快速整数?什么定义了一个整数有多快?

python - 多列高效搜索

arrays - 结构 : Fast assignment 的 Matlab 数组

java - 检查返回值是否不为空,如果是,则在一行中使用一个方法调用将其分配

java - 跟踪文档位置变化

java - 快速绘制任意点的集合

java - 使用 TextureView 缩放 Camera2 预览

c# bitarray 索引的正位

派生类中的 C++ 赋值运算符