【发布时间】:2010-12-27 18:40:21
【问题描述】:
假设我想用整数 (x,y) 坐标存储 n 个点。我可以使用 2-d (2Xn) 数组或使用列表/集合/或 n 个对象的数组,其中每个对象有 2 个整数字段来存储坐标。 据我所知,二维数组选项更快并且消耗更少的内存,但我不知道为什么?详细的解释或带有详细信息的链接表示赞赏。
【问题讨论】:
-
为什么要用二维的n*n数组只存储n个点?
标签: performance memory
假设我想用整数 (x,y) 坐标存储 n 个点。我可以使用 2-d (2Xn) 数组或使用列表/集合/或 n 个对象的数组,其中每个对象有 2 个整数字段来存储坐标。 据我所知,二维数组选项更快并且消耗更少的内存,但我不知道为什么?详细的解释或带有详细信息的链接表示赞赏。
【问题讨论】:
标签: performance memory
这是一个非常广泛的问题,涉及到很多部分。首先,这与您使用的语言有关。让我们以 Java 为例。
当你创建一个对象时,它继承自主对象类。创建对象时,开销来自用户定义的类继承自Object。编译器必须在内存中虚拟化某些方法调用,以便当您调用.equals() 或.toString() 时,程序知道要调用哪一个(即您的类的.equals() 或Object 的.equals()) .这是通过查找表完成的,并在运行时使用指针确定。
这称为虚拟化。现在,在java中,数组实际上是一个对象,所以你真的不会从数组数组中获得太多。事实上,使用自己的类可能会做得更好,因为您可以限制与其关联的元数据。 java中的数组存储长度信息。
但是,许多集合确实有与之相关的开销。 ArrayList 例如将调整自身大小并将有关自身的元数据存储在内存中,您可能不需要。 LinkedList 具有对其他节点的引用,这是对其实际数据的开销。
现在,我所说的仅适用于 Java。在其他 OO 语言中,对象的内部行为不同,有些可能效率更高/更低。
在像 C++ 这样的语言中,当你分配一个数组时,你实际上只是获得了一块内存,你想用它做什么取决于你。从这个意义上说,它可能会更好。如果您使用覆盖(关键字virtual),C++ 的对象具有类似的开销,因为它将在内存中创建这些虚拟查找。
【讨论】:
一切都取决于您使用存储空间的效率以及您的访问要求。必须留出内存来保存一个 10,000 x 10,000 的数组来仅存储 10 个点,这将是一种可怕的内存浪费。另一方面,如果您花费大量时间迭代列表以在存储的 10,000,000 个点中找到您实际需要的一个点,那么通过将点存储在链表中来节省内存也是毫无意义的。
两者的一些缺点都可以克服。稀疏数组,通过一些规则对列表进行预排序,以便“需要”点浮动到顶部,等等......
【讨论】:
在大多数语言中,对于多维数组,比如 AxB,您只需有一块足够大的内存来保存 A*B 对象,当您查找元素 (m,n) 时,您需要做的就是找到位置 m*A+b 处的元素。当您有一个对象列表时,每个列表都会产生开销,而且查找比简单的地址计算更复杂。
如果矩阵的大小不变,则二维数组是最快的选择。如果它需要增长和缩小,尽管您可能别无选择,只能使用第二种方法。
【讨论】: