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

java优化nitpick:是否比在铸造前调用instanceof进行检查更快地投射某些东西并使其引发异常?

柯波娃
2023-03-14
问题内容

在有人说什么之前,我只是出于好奇而问。我不打算根据此答案进行任何过早的优化。

我的问题是关于使用反射和投射的速度。标准的说法是“反射很慢”。我的问题是到底哪一部分慢,为什么?特别是在比较某物是否为另一个实例的父对象时。

我非常有信心,仅将一个对象的类与另一个Class对象进行比较就和任何比较一样快,大概只是对已经存储在对象状态中的单例对象进行直接比较;但是如果一个班级是另一个班级的父级呢?

我通常认为instanceof与常规班级检查一样快,但是今天我想到了,似乎必须在“幕后”进行一些反思instanceof才能起作用。我在网上检查了一下,发现一些地方的人说的instanceof很慢。大概是由于需要比较对象的父对象的反射

这就引出了下一个问题,那就是铸造。如果我将某物作为对象,则不会得到ClassCastException。但是,如果将对象强制转换为自身的父对象,则不会发生这种情况。本质上instanceof,我在运行时执行转换或执行该操作的逻辑,对吗?我从未听说过有人暗示过铸造对象可能很慢。诚然,并非所有强制类型转换都是针对所提供对象的父对象,但是很多强制类型转换
都是 针对父类。但是从来没有人暗示过这可能很慢。

那是什么。是instanceof真的没有那么慢?都instanceof和铸造父类有点慢?还是有某种原因可以比instanceof通话更快地进行转换?


问题答案:

与往常一样,尝试并查看您的特定情况,但是:

-异常昂贵,非常明显。

-将异常用于代码流几乎总是一个坏主意

编辑:好的,我很感兴趣,所以我写了一个快速测试系统

public class Test{

    public Test(){
        B b=new B();
        C c=new C();


        for(int i=0;i<10000;i++){
            testUsingInstanceOf(b);
            testUsingInstanceOf(c);
            testUsingException(b);
            testUsingException(c);
        }
    }

    public static void main(String[] args){

        Test test=new Test();

    }

    public static boolean testUsingInstanceOf(A possiblyB){
        if (possiblyB instanceof B){
            return true;
        }else{
            return false;
        }
    }
    public static boolean testUsingException(A possiblyB){
        try{
            B b=(B)possiblyB;
            return true;
        }catch(Exception e){
            return false;
        }
    }


    private class A{

    }
    private class B extends A{

    }
    private class C extends A{

    }        
}

个人资料结果:

by InstanceOf: 4.43 ms
by Exception: 79.4 ms

正如我所说,非常昂贵

甚至当它始终是B时(模拟当您99%确信B时,您只需要确保它仍然不会更快即可即可即可:

剖析结果始终为B:

by InstanceOf: 4.48 ms
by Exception: 4.51 ms


 类似资料:
  • 问题内容: 试一试无用的东西只是看看此代码是否引发了特定的异常,这是一个好方法吗? 我想在引发异常时做点什么,否则就什么也不做。 有太多的先决条件要测试,构造函数BigDecimal()始终检查所有条件,因此这似乎是最简单的方法。 问题答案: 通常,应避免这种做法。但是,由于没有实用程序方法,所以这是要走的路。 正如Peter Tillemans在评论中指出的那样,将此代码放在称为的实用程序方法中

  • 问题内容: 我想知道只有Integer.parseInt(无论如何)都不会失败的情况下才能做些什么。 更具体地说,我有一个jTextArea用户指定值,由换行符分隔。 我想检查每一行,看看是否可以转换为整数。 想出了类似的东西,但是不起作用: 任何帮助表示赞赏。 问题答案:

  • 问题内容: 我应该测试某些东西是有效的还是只是为了做它并捕获异常? 有没有可靠的文档说一种方法是首选? 还有一种方法更 pythonic 吗? 例如,我应该: 要么: 一些想法… PEP 20说: 错误绝不能默默传递。 除非明确地保持沉默。 应该使用a而不是an解释为无声传递的错误吗?如果是这样,您是否通过以这种方式使用它来明确使其静音,从而使其正常运行? 我 并不是 指只能以一种方式做事的情况;

  • 问题内容: 我想检查一个对象是否是类的实例或的子类。 例如,如果is是类,我想成为并且也要成为。 我希望它也适用于装箱的原始类型。例如,如果是那么应该是。 有这样的事吗?如果没有,如何实现这种方法? 问题答案: Class.isInstance可以满足您的需求。 当然,如果可以使用它,则不应该使用它,但是对于反射场景,它通常派上用场。

  • 问题内容: 如果“表”没有行。什么是最简单的检查方法? 问题答案: 您可以使用mysql_num_rows($ results) 来检查是否返回了0行,或者使用以下更快的替代方法:

  • 问题内容: 要检查奇数和偶数整数,最低位检查比使用模数检查更有效吗? 问题答案: 是的 标准库中的模块是检查这些内容的方式。例如: 如您所见,在我的(第一天==旧==慢;-) Macbook Air上,该解决方案的重复速度比该解决方案快7到18纳秒。 不仅告诉您更快的方法,而且告诉您执行速度快了多少(只需运行几次测试),这通常表明它极其重要(调用函数的开销大约为400时,您 真的 关心10纳秒的差