首先 - 我有一个字符串文件。最小的文件大约是20个字符串。最大的文件目前有12,000个不同长度的字符串(从一个字符到大约80个字节)。我怀疑将来我可能会有一个60,000字符串文件。
最初,我创建了一个标准的字符串数组,默认大小为200,并将大小加倍,并在需要时将数组复制到新数组(同时将文件读入数组)。这种方法非常快。但是,搜索或包含等方法的可读性和额外编码并不吸引人。我尝试了一个List接口 - 并使用典型的list.add(行)读取文件,直到没有更多行。
我的问题是:ArrayList的默认大小是什么<>这种方法会导致分配/调整太多吗?关于这两种方法,我应该知道哪些性能点,哪种更好?
答案 0 :(得分:3)
ArrayList默认大小为10.即使从大小1开始,摊销成本也不是很贵。如果以高容量初始化,您可以将成本降低到接近0:
List myList = new ArrayList<String>(100000);
此外,您应该意识到List
接口本质上没有任何性能标准。它的实现如LinkedList
和ArrayList
。
编辑:我很懒,永远不会使用直线阵列。 ArrayList
几乎是包含内置add()
和remove()
等所有函数的数组。传统的列表实现ArrayList
是我通常会考虑的替代方案,但是如果你要搜索的东西我建议在你加载它之后对它进行一次排序,并使用ArrayList
来利用二进制搜索。
答案 1 :(得分:2)
大多数集合都有一个构造函数,允许您设置初始容量。我知道ArrayList还有一个方法,允许您将列表的容量增加到设置的最小数量ensureCapacity
,并且这些设置适当地设置会对使用集合的时间成本产生重大影响。 / p>
答案 2 :(得分:0)
我假设您正在尝试区分使用LinkedList和ArrayList。
从您的问题来看,看起来您关心的是添加和搜索功能。
如果您正在进行大量的一次性添加,则LinkedList将更快,因为它总是具有添加的O(1)成本,而阵列必须定期加倍。虽然正如@bdares指出的那样,你可以指定一个很大的初始容量,尽管你可能最终会浪费大量的内存来做这件事。
就包含而言,由于缓存局部性,ArrayList会更快。虽然两者都采用线性搜索,但ArrayList的循环速度会更快。
我可能会建议,如果你不关心你检索事物的顺序,那么如果你想要做很多包含调用的话,可以使用HashMap。这将明显加快。
答案 3 :(得分:0)
这听起来像是对我的过早优化(除非您编写移动或动力不足的硬件)。简短回答:总是使用ArrayList,除非你有一个非常明确的理由不这样做。
毫无疑问,你会得到关于调整大小,初始分配大小等成本的回应......但实际上,在处理方面加载/操作60k字符串绝对花生在今天的硬件上的时间。从对象分配和一般内存操作速度非常慢的日子开始,许多老派的java人仍然存在宿醉。
一般情况下,通过滚动自己比Java.util更“了解”问题域的实现,几乎总能获得轻微的性能提升,但这种努力很少值得。我只是从一个ArrayList开始,大小说60k元素(就内存使用而言,它也是绝对的花生)。
我最近参与了一个项目,该项目管理了价值1-2亿的数百万字符串的复杂数据结构,标准的开箱即用的ArrayList和HashMap绰绰有余。