在这里调用实例方法或声明变量是否更好?

时间:2018-05-13 05:23:02

标签: java

以下两种方法可以将一个有序的扑克牌副牌合并到一个有序牌组中:

方法1:

public static Deck merge(Deck d1, Deck d2) {
  Deck result = new Deck(d1.cards.length + d2.cards.length);
  int i = 0;
  int j = 0;

  for (int k = 0; k < result.cards.length; k++) {
    if (j >= d2.cards.length || i < d1.cards.length && d1.cards[i].compareTo(d2.cards[j]) <= 0) {
      result.cards[k] = d1.cards[i];
      i++;
    } else {
      result.cards[k] = d2.cards[j];
      j++;
    }
  }
  return result;
}

方法2:

public static Deck merge(Deck d1, Deck d2) {
  Deck result = new Deck(l1+l2);
  Card[] c1 = d1.getCards();
  Card[] c2 = d2.getCards();
  int l1 = c1.length;
  int l2 = c2.length;
  Card[] sorted = new Card[l1+l2];
  int i = 0;
  int j = 0;

     for (int k = 0;k<sorted.length;k++){
        if (j >= c2.length || i < c1.length && c1[i].compareTo(c2[j]) <= 0){
           sorted[k] = c1[i];
           i++;
        } 
        else {
           sorted[k] = c2[j];
           j++;
        }
     }
  }
  result.cards = sorted;
  return result;
}

哪种方法更有效?实际上有什么区别吗?

据我所知,第一种方法必须生成更大量的对象来完成一次运行,比方说,两个26卡子甲板。但是,该方法本身会存储较少的信息,这使我怀疑哪种方法更有效。

我知道在这个规模上它可能并不重要,但作为一个对Java不熟悉的人,我很想知道什么是最佳实践以及为什么。我已经尝试过搜索类似的情况,但还没有找到任何机会。如果有人能指出我正确的方向,我们将非常感激。

2 个答案:

答案 0 :(得分:2)

由于getCards()只是返回一个引用变量(即它没有复制cards数组),性能差异可能最小。

唯一可行的方法是对应用程序的两个版本进行基准测试。但如果衡量的差异超过几个百分点,基准 1 可能存在缺陷!

我建议不要浪费你的时间&#34;在这个级别进行优化&#34;除非你有明确的证据表明:

  1. 代码太慢了,
  2. 您有明确的证据表明您要优化的代码是导致缓慢的主要因素。
  3. 换句话说,基准然后配置文件然后优化代码中值得优化的部分。

    1 - 建议您在进入编码之前阅读如何编写声音基准。从:How do I write a correct micro-benchmark in Java?开始。

答案 1 :(得分:1)

您的第一种方法将创建两个对象 - 新的Deck对象,以及存储卡的数组(由Deck构造函数创建的数组)。您的第二种方法将创建3个对象 - 新Deck,由Deck构造函数创建的数组,以及名为sorted的数组。

但是,这并不重要,因为您根本没有创建Card个对象。您只是将两个甲板中Card个对象的引用复制到新的甲板上!将Card分配给数组不会创建新卡。它就像以下一样不会创建两个对象:

Object obj = new Object();
Object obj2 = obj;

所以实际上这两种方法是相同的。我建议你使用你认为最具可读性的那个。