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

Java思考:为什么这么慢?

姜嘉赐
2023-03-14
问题内容

我一直基于Java的缓慢性而避免使用Java反射soley。我在当前项目的设计中达到了可以使用它的目的,这将使我的代码更具可读性和雅致性,因此我决定尝试一下。

两者之间的差异让我感到惊讶,有时我发现运行时间几乎快了100倍。即使在这个仅实例化一个空类的简单示例中,它也是令人难以置信的。

class B {

}

public class Test {

    public static long timeDiff(long old) {
        return System.currentTimeMillis() - old;
    }

    public static void main(String args[]) throws Exception {

        long numTrials = (long) Math.pow(10, 7);

        long millis;

        millis = System.currentTimeMillis();

        for (int i=0; i<numTrials; i++) {
            new B();
        }
        System.out.println("Normal instaniation took: "
                 + timeDiff(millis) + "ms");

        millis = System.currentTimeMillis();

        Class<B> c = B.class;

        for (int i=0; i<numTrials; i++) {
            c.newInstance();
        }

        System.out.println("Reflecting instantiation took:" 
              + timeDiff(millis) + "ms");

    }
}

真的,我的问题是

  • 为什么这么慢?我在做错什么吗?(即使上面的示例也说明了区别)。我很难相信它真的比普通实例慢100倍。

  • 还有别的可以更好地用于将代码视为数据的东西吗(请记住,我暂时仍然使用Java)


问题答案:

您的测试可能有缺陷。通常,尽管JVM可以优化常规实例,但不能针对反射用例进行优化。

对于那些想知道现在几点的人,我添加了一个预热阶段,并使用数组来维护创建的对象(与实际程序可能执行的操作更相似)。我在OSX,jdk7系统上运行了测试代码,并得到了以下信息:

反映实例化耗时:5180ms
正常实例化耗时:2001ms

修改后的测试:

public class Test {

    static class B {

    }

    public static long timeDiff(long old) {
        return System.nanoTime() - old;
    }

    public static void main(String args[]) throws Exception {

        int numTrials = 10000000;
        B[] bees = new B[numTrials];
        Class<B> c = B.class;
        for (int i = 0; i < numTrials; i++) {
            bees[i] = c.newInstance();
        }
        for (int i = 0; i < numTrials; i++) {
            bees[i] = new B();
        }

        long nanos;

        nanos = System.nanoTime();
        for (int i = 0; i < numTrials; i++) {
            bees[i] = c.newInstance();
        }
        System.out.println("Reflecting instantiation took:" + TimeUnit.NANOSECONDS.toMillis(timeDiff(nanos)) + "ms");

        nanos = System.nanoTime();
        for (int i = 0; i < numTrials; i++) {
            bees[i] = new B();
        }
        System.out.println("Normal instaniation took: " + TimeUnit.NANOSECONDS.toMillis(timeDiff(nanos)) + "ms");
    }


}


 类似资料:
  • 问题内容: 我是Go的新手,在浏览其他一些线程时遇到了以下代码行: 含义是什么?它是否指定将在if条件中分配某些内容(因为err似乎正在发生这种情况)?我在Wiki上找不到这种语法的示例,并且我很好奇它的用途。 问题答案: 因为返回两个值,所以如果需要它们中的任何一个,都必须在某个地方接收这些值。该是一个占位符,基本的意思是“我不关心这个特殊的返回值。” 在这里,我们只关心检查错误,而无需对实际的

  • 所以我有这行代码。它给了我输出[6,28]。你们知道为什么吗?我不知道有人想打印什么样的数字。

  • 问题内容: 这是什么? 这是有关PHP语法的不时出现的问题的集合。这也是一个社区Wiki,因此邀请所有人参与维护此列表。 为什么是这样? 过去通常很难找到有关运算符和其他语法标记 的问题。¹主要思想是具有指向现有问题的链接,因此我们更容易引用它们,而不必从PHP手册中复制内容。 我该怎么办? 如果有人因提出这样的问题而将您指向此处,请在下面找到特定的语法。PHP手册的链接页面以及链接的问题可能会回

  • 问题内容: 这是所有编程语言所共有的吗?在进行多次打印后再执行println似乎更快,但是将所有内容移动到字符串中并仅进行打印似乎最快。为什么? 编辑:例如,Java可以在不到一秒钟的时间内找到所有高达100万的质数- 但要进行打印,然后在自己的println中将它们全部输出可能需要几分钟!最多可打印100亿小时! 例如: 问题答案: 速度并不慢,而是由主机操作系统提供的与控制台连接的基础。 您可

  • 问题内容: 我对此感到困惑 现在让我们来看看numpy: 神圣的CPU周期蝙蝠侠! 使用改进,但恕我直言仍然不够 numpy.version.version =‘1.5.1’ 如果您想知道在第一个示例中是否跳过了列表创建以进行优化,则不是: 问题答案: Numpy已针对大量数据进行了优化。给它一个很小的3长度数组,毫不奇怪,它的性能很差。 考虑单独的测试 输出是 似乎是数组的归零一直花费在nump

  • 问题内容: Magento通常这么慢吗? 这是我的第一次使用体验,管理面板只需花一些时间即可加载和保存更改。这是带有测试数据的默认安装。 托管该服务器的服务器可超快地服务于其他非Magento站点。Magento使它如此缓慢的PHP代码有什么用,该如何解决? 问题答案: 我只是切身参与优化Magento的性能,但这是系统速度如此缓慢的一些原因 Magento的某些部分使用在MySQL之上实现的EA