3

我正在编写一个程序,它接受 400 个类型long,并将根据运行时的条件修改其中一些,我想知道是否使用ArrayList<Long>long[].

哪个会更快使用?我正在考虑使用long[],因为大小是固定的。

4

6 回答 6

17

当大小固定时,long[]速度会更快,但它允许的 API 可维护性较差,因为它不实现List接口。

注意 along[]更快有两个原因:

  1. 使用原始longs 而不是 box object Longs(也可以实现更好的缓存性能,因为longs 是连续分配的,并且Longs 不能保证)
  2. 数组是更简单和更有效的 DS。

尽管如此,为了更简单的可维护性 - 我会使用List<Long>, 除非性能在程序的这一部分非常关键。

如果你经常在一个紧密的循环中使用这个集合——并且你的分析器说它确实是一个瓶颈——那么我会切换到一个更有效的long[].

于 2012-12-26T06:56:12.433 回答
8

就速度而言,400 个项目的列表几乎无关紧要。如果您需要动态增加列表,ArrayList<Long>那就更好了;如果大小是固定的,long[]可能会更好(并且速度会更快,尽管在大多数情况下您可能不会注意到差异)。

于 2012-12-26T06:56:53.160 回答
5

其他答案中没有提到的几件事:

  • 泛型集合实际上是Objects 的集合,或者更好地说,这就是 Java 编译器将对其进行的处理。这段时间long[]将永远保持现状。

  • 第一个要点的结果是,如果您做某事最终将其他内容Long放入您的集合中,在某些情况下编译器会允许它通过(因为 Java 类型系统不健全,例如,它允许您upcast 然后重新转换为完全不同的类型)。

  • 这两者的一个更普遍的结果是 Java 泛型是半生不熟的,在一些不那么琐碎的情况下,例如反射、序列化等,可能会让您“吃惊”。事实上,使用普通数组比使用泛型更安全。


package tld.example;

import java.util.List;
import java.util.ArrayList;

class Example {

    static void testArray(long[] longs) {
        System.out.println("testArray");
    }

    static void testGeneric(List<Long> longs) {
        System.out.println("testGeneric");
    }

    @SuppressWarnings("unchecked")
    public static void main(String... arguments) {
        List<Long> fakeLongs = new ArrayList<Long>();
        List<Object> mischiefManaged = (List<Object>)(Object)fakeLongs;
        mischiefManaged.add(new Object());
        // this call succeeds and prints the value.
        // we could sneak in a wrong type into this function
        // and it remained unnoticed
        testGeneric(fakeLongs);

        long[] realLongs = new long[1];
        // this will fail because it is not possible to perform this cast
        // despite the compiler thinks it is.
        Object[] forgedLongs = (Object[])(Object)realLongs;
        forgedLongs[0] = new Object();
        testArray(realLongs);
    }
}

这个例子有点做作,因为很难想出一个简短的令人信服的例子,但相信我,在不那么琐碎的情况下,当你必须使用反射和不安全的强制转换时,这是很有可能的。

现在,您必须考虑,除了合理之外,还有一个传统。每个社区都有一套它的习俗和传统。有很多肤浅的信念,例如这里所说的那些。当有人声称实现ListAPI 是无条件的善,如果这没有发生,那么它一定是坏的......这不仅仅是一种主流观点,这是绝大多数 Java 程序员所相信的。毕竟,它没有没那么重要,而 Java,作为一门语言还有很多其他的缺点......所以,如果你想确保你的工作面试或只是避免与其他 Java 程序员发生冲突,那么无论出于何种原因,请使用 Java 泛型. 但是,如果您不喜欢它-好吧,也许只是使用其他语言;)

于 2012-12-26T08:43:27.613 回答
2

long[] 既快得多,又占用更少的内存。阅读“Effective Java”第 49 条:“Prefer primitive types to boxed primitives”

于 2012-12-26T06:57:38.047 回答
2

我认为使用 ArrayList 更好,因为它更容易长期维护。将来,如果您的数组大小增加到超过 400,那么维护 long[] 会产生很多开销,而 ArrayList 会动态增长,因此您无需担心大小增加。
此外,ArrayList 以比静态数组 (long[]) 更好的方式处理元素的删除,因为它们会自动重新组织元素,以便它们仍然显示为有序元素。静态数组在这方面更糟糕。

于 2012-12-26T07:13:20.160 回答
1

为什么不使用适用于原始类型的众多列表实现之一呢?例如TLongArrayList。它可以像 Javas List 一样使用,但基于 long[] 数组。所以你有双方的优势。

HPPC 简要概述了一些库:https ://github.com/carrotsearch/hppc/blob/master/ALTERNATIVES.txt

于 2017-09-29T19:18:48.430 回答