【问题标题】:which one is better from performance point of view..arraylist or array?从性能的角度来看,哪一个更好..arraylist 或 array?
【发布时间】:2012-04-10 17:00:30
【问题描述】:

我想存储 50000 个或更多字符串,我需要执行几个操作,例如检索特定字符串、删除特定字符串等。我只有两个选项可供选择,它们是数组列表和数组存储它们。从性能的角度来看,哪个更好?

【问题讨论】:

    标签: java arrays collections


    【解决方案1】:

    两者都没有。如果您想检索特定字符串(例如获取字符串“Foo”)并删除特定字符串(例如删除“Foo”),我会考虑使用Set

    数组列表或数组将为您提供 O(N) 检索(除非您对其进行排序)。 Set 通常会给您至少 O(lg N) 的时间来查找特定项目。

    【讨论】:

    • 为什么是Set 而不是Map?他可能想要重复
    • 这个问题没有给出与字符串相关的值的任何信息,所以Set 似乎更自然。
    【解决方案2】:

    ArrayList 由数组支持,因此在性能方面您应该看不出有什么区别。

    如果您的要求没有错误,并且确实您只能在数组列表和原始数组中进行选择,我建议您使用数组列表,因为您拥有所有 API 来操作您必须自己编写的可用数据对于Strings 的原始数组。

    【讨论】:

    • 抽象总是至少会产生一些的开销。 Python 由 C“支持”,而 C 由 x86“支持”(至少在我的计算机中),但这并不意味着我使用 Python 可以获得与使用汇编代码相同的性能。
    • @NullUserException:我曾经坚信这一点,但我一直在阅读各种链接,Java(由 C 解释和支持)并不比 C++ 慢,而且偶尔会更快跨度>
    • 通常情况下,ArrayList 的 indexOf 操作(这是 OP 提到的操作之一)与您对数组所做的完全一样 - 而不是一行额外的代码。
    • @assylias, wrt indexOf 即使它与您对数组所做的完全一样,它仍然是一个额外的方法调用。诚然,它可以忽略不计,而且很有可能会被编译掉(我真的不知道),但数组应该总是和 ArrayList 一样快或(可以忽略不计)快。
    • @emory 什么额外的方法调用?编辑:好的理解,调用 indexOf 的事实......我想那是几纳秒。但我希望即使使用数组,代码也不会是一个大的 1000 LOC 方法!
    【解决方案3】:

    数组在性能方面比数组列表更有效,但除非您知道要放入数组中的元素数量,否则数组列表将是更好的选择,因为数组列表的大小可以根据需要增长,而静态数组则不能。

    【讨论】:

    • 奇怪的答案。1)你为什么要假设一个静态数组?2)一个数组列表是由一个数组支持的。
    • 静态数组可以像 ArrayList 一样“增长”,唯一的区别是您必须自己编写增长函数(创建新数组并复制数据),而 ArrayList 会自动为您完成。
    • 一个数组[] 在创建时的大小是静态的,是的,一个数组列表在内部使用一个数组,但它们并不相同,因为当您创建一个新数组并自己复制原始数组中的数据时刚刚重新发明了arraylist并回到了O(n)。问题是关于哪个性能更快,而数组在性能方面比 arraylist 更快。
    【解决方案4】:

    数组总是比ArrayList 有更好的性能。部分原因是,当使用数组时,您不必支付对其元素进行类型转换的额外成本(使用泛型并不意味着类型转换消失,只是它们从普通视图中隐藏)。

    为了说明我的观点:Trovefastutil 是两个非常快速的 Java 集合库,它们依赖于提供特定类型集合的事实,而不是像 ArrayList 那样基于对象的实现。

    此外,使用get() 方法访问元素(尽管很小)和调整大小操作的成本是有成本的,这在具有许多插入和删除的巨大ArrayLists 中可能很重要。当然,数组不会发生这种情况,因为它们的本质是固定大小的,这既是优点也是缺点。

    回答您的问题:如果您事先知道需要的元素数量,并且这些元素不会发生太大变化(插入、删除),那么您最好的选择是使用数组。如果需要一些修改操作并且性能至关重要,请尝试使用 Trove 或 fastutil。

    【讨论】:

    • 你所说的对我来说是有道理的。但如果没有测量,我不确定它们之间是否存在这样的性能差异。你有一些指定测量的链接吗?
    【解决方案5】:

    检索特定字符串,删除特定字符串...我认为 ArrayList 不是最好的解决方案。看看 HashSet 或 LinkedHashSet。

    【讨论】:

      【解决方案6】:

      如果您查看source code of ArrayList,您会看到:

        107       /**
        108        * The array buffer into which the elements of the ArrayList are stored.
        109        * The capacity of the ArrayList is the length of this array buffer.
        110        */
        111       private transient Object[] elementData;
      

      它在内部使用一个数组。

      所以 ArrayList 永远不会比使用数组更快。

      【讨论】:

        【解决方案7】:

        如果您最初正确调整 ArrayList 的大小,主要区别将来自添加,它会进行范围检查,您可以使用数组摆脱。但我们在这里谈论的是几个 CPU 周期。

        除此之外应该没有明显的区别。例如,ArrayList 中的indexOf 方法如下所示:

           public int indexOf(Object o) {
               if (o == null) {
                   for (int i = 0; i < size; i++)
                       if (elementData[i]==null)
                           return i;
               } else {
                   for (int i = 0; i < size; i++)
                       if (o.equals(elementData[i]))
                           return i;
               }
               return -1;
           }
        

        【讨论】:

          猜你喜欢
          • 2014-09-30
          • 2012-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多