【问题标题】:Java: Comparable vs Comparator - Memory & PerformanceJava:Comparable vs Comparator - 内存和性能
【发布时间】:2020-06-23 12:33:52
【问题描述】:

在我的一次采访中,有人问我

Comparable 和 Comparable 之间的性能差异是什么? 比较器?

我回答说我不知道​​。面试官说,

如果 Comparable 由类 Employee 实现,则为 5000 Employee 对象被创建并添加到一个 ArrayList 中,会有 5000 个对象,在堆内存中有 compareTo 方法。所以除非 绝对必要,不要使用 Comparable。与比较器, 上面提到的内存开销被消除了。

他说的对吗?

【问题讨论】:

  • 那是……错了……类上的其他方法并不意味着该方法的实例需要更多内存。
  • 我同意约阿希姆的观点。该方法在类上,而不是在单个对象上。实际上,最好使用 Comparable 接口并将 Comparator 用于您无法控制的对象,或者如果您正在执行异常的复杂比较。

标签: java performance collections comparator comparable


【解决方案1】:

这个答案不正确。

添加实现的接口或方法不会影响类的各个实例所需的内存。

首先,从概念上讲它没有意义。

实现的接口和方法是每个类的信息。同一类的两个实例将始终实现完全相同的接口并具有完全相同的方法。因此,JVM 按对象存储这些信息是没有意义的。

其次,您可以使用如下示例代码轻松验证:

public class MyClass implements Comparable<MyClass> {

  private final long l;

  MyClass(long l) {this.l = l;}

  @Override
  public int compareTo(MyClass o) {
    return 0;
  }

  public static void main(String[] args) {
    long l = 0;
    try {
      var list = new ArrayList<MyClass>();
      while (true) {
        list.add(new MyClass(l++));
      }
    } catch (OutOfMemoryError e) {
      System.out.println("Created " + l + " objects before things went south ...");
    }
  }
}

使用 Java 11 使用 -Xmx32m 运行它会在每次运行时为我创建大约 200000 个对象(略有不同,可能是由于 GC 细节)。

删除Comparable 接口和/或compareTo 方法不会显着改变该值。

您可以尝试添加其他字段或删除l,这会更改数字。

【讨论】:

  • 还有另一种观点。让我们暂时假设,有一个特殊的 JVM 需要每个实例中的每个方法的内存。然后,java.lang.Object 确实已经定义了 11 种方法。任何现实生活中的Employee 类建模一些业务逻辑肯定会增加另外一两个。而且面试官真的浪费时间讨论单一的compareTo 方法……
猜你喜欢
  • 1970-01-01
  • 2012-12-15
  • 2011-08-21
  • 2016-10-08
  • 2010-11-10
  • 2012-03-11
  • 2013-11-04
  • 2012-10-14
  • 2013-05-09
相关资源
最近更新 更多