【问题标题】:Does instanceof operator generate a lot of overhead ? Why? [duplicate]instanceof 运算符会产生很多开销吗?为什么? [复制]
【发布时间】:2011-02-11 19:51:28
【问题描述】:

我的项目中有一位同事,他非常反对使用instanceof 运算符,因为它“产生大量开销”,这是什么原因?是真的吗?

是否有另一种方法来检查对象的类型而不是使用它?

因为我发现它在某些场合非常有用。

【问题讨论】:

  • 我非常怀疑它,因为它是一个关键字,编译器通常可以对类型进行静态推断,即使它不能,它也只需从某个已加载类的表中读取即可查看如果当前类是子类。

标签: java optimization casting


【解决方案1】:

它确实会产生一些开销,并与随后的强制转换相结合。使用最新版本的 Java,开销已经减少。但无论如何,这是微优化——也就是说,在一般情况下你不应该担心它。

反对instanceof 的真正理由是,在许多情况下,有更好的 OOP 方法来实现所需的行为。

【讨论】:

  • +1 说明 instanceof 在使用前需要仔细考虑的真正原因。我看到很多代码应该使用 OO 范例来实现一大组 if instanceof 语句。
  • @Bozho,您能提供一种替代方法来代替使用可用于减少开销的 instanceof 吗?
  • @Deepak - 多态性。有时是访客模式。
  • @Bozho,任何可以证明 instanceOf 确实产生开销的工作示例......我如何针对多态行为模拟它
  • @to任何人,不要考虑这样的优化,编译器在优化你的代码方面非常不错,不要编写微基准测试,除非你完全确定你理解为什么微优化-benchmark 可能会“受苦”。
【解决方案2】:

如果编译器可以证明实例,它可能会也可能不会产生任何开销。 即使编译器不能立即证明目标,开销也很小。几个 cpu 时钟(尤其是如果正确预测了 instanceof 跳转)。

instanceof 之后的强制转换通常是免费的。

(注意:编译器指的是 JIT)

【讨论】:

  • :) 获得了更多的代表。比我能用的,所以人们可以修复错别字,如果他们愿意的话。除非我忘记了,否则我倾向于在社区 wiki 下发帖。顺便说一句,iirc,instanceof 对于没有子类的类(Long/Double/String/URL 等)来说,可以像单个 CPU 时钟一样便宜
  • 人们仍然可以编辑您的帖子。因此,请随时发布常规答案;)
  • 不,你需要相当高的代表。不管怎样,很少有人敢这样做。代表被高估了:)
  • 无论代表如何,您都可以提出修改建议。
【解决方案3】:

没有严重的开销。它几乎肯定比本土的 getType() 式解决方案便宜。铸造虽然不是免费的,但也很便宜。

正如 Bozho 所说,这可能表明设计存在缺陷,但在某些情况下,它是最实用的选择,因此不应立即忽视。

【讨论】:

  • 选角虽然不是免费的,但也很便宜。instanceof之后免费
【解决方案4】:

主要问题是它会产生代码异味。如果您使用多态性,这是一种更好的设计方法。性能成本可能在 10 到 100 纳秒左右,具体取决于调用的复杂性以及您从该代码行调用的实现方法的数量。

【讨论】:

  • 您是如何计算 10 纳秒开销的?是否还有另一个更知名的手术需要大约相同的时间?
  • @LouisCAD 这是一个估计平均值。注意:这将取决于许多因素,所以我可能会更多。
【解决方案5】:

实际上,instanceof 返回 true 和对该类型的强制转换并不完全等价——当前者返回 false 时,后者可能会成功。所以,即使有这样的事情,

String s = someMethodReturningString();
Object o = s;
if (o instanceof String) {
   ...
}

编译器必须在此处至少生成一个检查o != null

但实际上,它是可以忽略的。

【讨论】:

  • 不要进入参数,而是如何将整数分配给字符串,如果方法不返回 null(永远)instanceof 是死代码。通常空检查是 1cpu 时钟,顺便说一句
  • @bestsss:啊,我先用 Integer 写了这个例子,然后改成 object 来避免包装/解包的麻烦。谢谢指出,我会改正的。
  • 如果 JIT 可以内联代码(不是一些多目标虚拟代码)并且如果最终结果永远不会为空,则 (o instanceof String) 将被省略,我试图解释它:唯一的操作 ppl在性能方面真正应该考虑的是访问内存,其余的都得到了很好的优化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
  • 2020-01-10
  • 2010-10-07
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多