当前位置: 首页 > 面试题库 >

声明64个元素的多个数组比声明65个元素的数组快1000倍

池赞
2023-03-14
问题内容

最近,我注意到声明包含64个元素的数组比声明具有65个元素的相同类型的数组要快得多(> 1000倍)。

这是我用来测试的代码:

public class Tests{
    public static void main(String args[]){
        double start = System.nanoTime();
        int job = 100000000;//100 million
        for(int i = 0; i < job; i++){
            double[] test = new double[64];
        }
        double end = System.nanoTime();
        System.out.println("Total runtime = " + (end-start)/1000000 + " ms");
    }
}

这将运行在大约6毫秒,如果我更换new double[64]new double[65]它需要大约7秒。如果作业分布在越来越多的线程中,那么这个问题就会成倍地恶化,这就是我的问题所在。

不同类型的数组(例如int[65]或)也会发生此问题String[65]。大字符串不会发生此问题:String test = "many characters";,但将其更改为时确实会发生String test = i + "";

我想知道为什么会这样,是否有可能规避这个问题。


问题答案:

您正在观察到由Java VM的JIT编译器完成的 优化
所引起的行为。此行为在最多包含64个元素的标量数组中触发时可重现,而在大于64个数组中则不会触发。

在进入细节之前,让我们仔细看一下循环的主体:

double[] test = new double[64];

身体没有作用 (可观察到的行为)
。这意味着无论是否执行该语句,在程序执行之外都没有区别。整个循环也是如此。因此,可能发生的情况是,代码优化器将循环转换为具有相同功能和不同定时行为的某种东西
(或什么都没有)

对于基准测试,您至少应遵守以下两个准则。如果您这样做,则差异会小得多。

  • 通过多次执行基准测试来预热JIT编译器(和优化器)。
  • 使用每个表达式的结果并将其打印在基准测试的末尾。

现在让我们详细介绍。毫不奇怪,对于不大于64个元素的标量数组会触发优化。优化是转义分析的一部分。它将小对象和小数组放到堆栈上,而不是在堆上分配它们-
甚至更好地完全优化它们。您可以在下面由Brian Goetz在2005年撰写的文章中找到有关此信息的一些信息:

  • 重新审视城市绩效传奇:分配比您想象的要快,而且越来越快

可以使用命令行选项禁用优化-XX:-DoEscapeAnalysis。标量数组的魔术值64也可以在命令行上更改。如果按以下方式执行程序,则包含64和65个元素的数组之间将没有区别:

java -XX:EliminateAllocationArraySizeLimit=65 Tests

话虽如此,我强烈不鼓励使用此类命令行选项。我怀疑这在实际应用中会带来巨大的不同。如果我完全确信其必要性,而不是根据某些伪基准测试的结果,则只能使用它。



 类似资料:
  • 案例:我有一个启用了Google身份验证方法的MVC5应用程序(基本上是带有框架视图的MVC5模板)。该应用程序已配置为接受电子邮件作为用户名,并将从Google分配的声明(如姓氏、givenname、电子邮件、nameidentifier等)存储到成员数据库(AspNetUserClaims)。 我已尝试使用Application_Start(示例)中的AntiForgeryConfig选项将令

  • 问题内容: 有没有一种方法可以在Java中声明数组元素?即 声明 数组引用 ,但是 数组元素 (例如)仍然不是易失的。所以我正在寻找类似的东西 但是那样行不通。有可能吗? 问题答案: 使用或或 所述类实现一个int数组,其单独的字段可与易失性的语义来访问,经由类的和的方法。调用然后从一个线程将保证另一个线程调用将读取值y(直到另一个值读取位置X)。 看到: 原子整数数组 原子长数组 原子引用数组

  • 问题内容: 我努力了: 首先,声明和初始化可以正常工作,但是第二,第三和第四不起作用。如何声明和初始化浮点数的const数组? 问题答案: 数组不是天生不变的。您无法使其保持恒定。 您可以获得的最接近的是: 请注意而不是:它可确保获得(固定大小)数组而不是切片。因此值不是固定的,但大小是固定的。

  • 问题内容: 我有一个包含两个类的元素,一个叫做“ rotate”,它将旋转元素360度,另一个叫做“ doublesize”,它将元素放大两倍于其正常大小: 我猜这是行不通的,因为这些类会覆盖彼此的属性? 我知道我可以很容易地在一条CSS规则中做到这一点,例如: 但是我希望能够在可能的情况下分别应用每个类。 问题答案: 我猜这是行不通的,因为这些类会覆盖彼此的属性? 正确。作为级联工作方式的副作用

  • 本文向大家介绍Visual Basic .NET声明一维数组并设置数组元素值,包括了Visual Basic .NET声明一维数组并设置数组元素值的使用技巧和注意事项,需要的朋友参考一下 示例 要么            

  • 问题内容: 有人遇到过这个问题吗?假设您有两个类似以下的数组 有没有一种方法可以比较b中a中的哪些元素?例如, 我正在尝试避免循环,因为要花费数百万个元素才能解决问题。有任何想法吗? 干杯 问题答案: 实际上,有一个比以下任何一种方法更简单的解决方案: 所得的c为: