Java:更快的重载或 if/else
Posted
技术标签:
【中文标题】Java:更快的重载或 if/else【英文标题】:Java: which is faster overloading or if/else 【发布时间】:2010-10-19 23:33:43 【问题描述】:我有子类,每个子类与其他成员一起携带不同类型的值。可能有LongObject、IntObject、StringObject等。
会给我一个值,可以是long、int、string等,我要分别创建一个LongObject、IntObject、StringObject等。
像下面 (a) 所示重载方法会更快还是只使用下面 (b) 所示的 elseif 会更快?
这可能不是明显的性能差异。无论如何,重载方法可能以与 if/else 类似的方式实现。我不知道。
我也可以听到你们中的一些人说只是测试它。当然,我应该这样做。我也想知道这种类型的重载是如何在后台处理的,如果有人知道的话。
请告诉我你的想法。
谢谢, jbu
一)
BaseObject getObject(long l)
return new LongObject(l);
BaseObject getObject(int i)
return new IntObject(i);
BaseObject getObject(String s)
return new StringObject(s);
...
b)
BaseObject getObject(Object x)
if(value is a long)
return new LongObject((Long)x);
else if(value is an int)
return new IntObject((Int)x);
else if(value is a String)
return new StringObject((String)x);
...
编辑:我想我并没有完全添加所有细节,你们中的一些人抓住了它。对于这两种选择,我仍然必须获取一个对象/值,并根据该值确定它是什么类型。因此,我仍然需要执行某种 if/else 操作才能使用重载方法。
【问题讨论】:
我对此类问题的个人哲学:时间吧!在每一个上运行几百万次迭代,看看哪一个需要更长的时间。 我就知道有人会这么说:) 只需创建一个测试并自己回答。 【参考方案1】:这里有一个巨大的差异:重载是在编译时选择的,而您的“if (value is a long)”将是一个执行时测试。
如果您在编译时知道类型,我强烈建议您使用该信息。如果你不这样做,那么重载选项无论如何都不可行。
编辑:评论建议我详细说明在编译时选择的重载。
编译器根据参数的编译时间信息选择调用哪个方法签名。这与 覆盖 不同,其中要使用的方法实现由方法的实际目标的类型决定。
这是一个例子:
public class Test
public static void main(String[] args)
Object x = "I'm a string";
foo(x);
public static void foo(String x)
System.out.println("foo(String)");
public static void foo(Object x)
System.out.println("foo(Object)");
这会打印出foo(Object)
,因为x
的编译时类型是Object
,而不是String
。 x
所引用的对象的执行时类型是String
并不意味着调用了foo(String)
。
【讨论】:
我不确定“在编译时选择重载”是什么意思。你能详细说明一下吗?我看到这些方法是在编译时编译的(...),但对这些方法的调用可能不是。我错过了什么吗? 哦,我明白了你的陈述背后的逻辑。你是说我需要一个 if/else 语句来决定使用哪个重载方法。如果我要获得一个未知类型的对象,我需要在使用重载方法之前对其进行 if/else 转换。对吗? @jbu:是的,我相信你现在明白了。 谢谢,它帮助我了解了幕后发生的事情。【参考方案2】:重载解决方案更快(更好),因为它是在编译时解决的。
基本上,编译器会在您向其传递值时确定调用哪个方法。当你调用 getObject("abc") 时,编译器会发出对方法的调用:
BaseObject getObject(String s)
return new StringObject(s);
而不是尝试通过您的 if ... else 状态并在运行时评估对象类型(这是一个缓慢的活动)。
【讨论】:
【参考方案3】:不用担心,除非每秒测试数百万次,否则无关紧要。
【讨论】:
【参考方案4】:a)(重载)会更快,因为它为即时编译器提供了优化的机会。它可以决定内联新对象的创建。
【讨论】:
【参考方案5】:任何时候您必须在运行时评估类型信息,这可能是一个相对较慢的操作。当您有选择时,编写在编译时这样做的代码几乎总是更可取的。
这通常被称为“早期绑定”与“后期绑定”。
【讨论】:
【参考方案6】:级联条件在 OO 编程中是不好的因果报应,在测试对象的类型时非常难看。该语言已经为测试之王提供了多态性。
另外,作为一个非 Java 人,我会使用 getLong(l)
、getInt(i)
、getString(s)
。
我发现方法重载比没有更令人困惑(恕我直言,静态类型不应该影响程序执行(除了优化方面(尽管看起来我不是 Lisper :))))
【讨论】:
【参考方案7】:最重要的是,getObj(int)、getObj(string) 等 - 如果您尝试传递未预期的内容,则会在编译时失败。
如果您允许将任何对象传递到方法中,您可能会有一个实例,其中应用程序试图传递该方法无法处理的东西,并且您最终会遇到一个丑陋的运行时错误。
【讨论】:
以上是关于Java:更快的重载或 if/else的主要内容,如果未能解决你的问题,请参考以下文章