javascript中null占用内存吗?

发布于 2024-11-17 05:08:44 字数 608 浏览 6 评论 0原文

我遇到以下情况:

var large = [a,b,c,d,e,f,g,h,i];
var small = [a2, b2, c2, null, null, null, null, null, null, i2];

两个数组的每个元素都是一个对象。

小数组包含与大数组相关的信息,但并非 large 的每个元素都需要 small 中的关联元素,因此我将其设置为 null代码>.但是,我仍然需要保持索引相同,以便我可以执行诸如 large[16].id + ': ' +small[16].description 之类的操作。我的数组的值大部分为 null 是否会导致内存使用量增加?

我的问题是,我是否最好执行诸如 small = [a2,b2,c2,i2] 之类的操作,并在诸如 a2.index = 0; 之类的属性中设置索引。 b2.index = 1 等等。

我还遇到了使用 undefined 的建议,甚至有人提到了实现链接列表。我认为我不需要实现链接列表,因为我不经常添加或删除元素。

I've got the following situation:

var large = [a,b,c,d,e,f,g,h,i];
var small = [a2, b2, c2, null, null, null, null, null, null, i2];

where every element of both arrays is an object.

The small array contains information related to the the larger one, but not every element of large requires an associated element in small and so I set it to null. However, I do still need to keep the indices the same so I can do things like large[16].id + ': ' + small[16].description. Does the fact that I've got an array that's mostly null in value result in increased memory usage?

My question is whether or not I'd be better off doing something like small = [a2,b2,c2,i2], and setting indices in properties like a2.index = 0; b2.index = 1 and so on.

I've also come across a suggestion to use undefined instead and someone even mentioned implementing linked lists. I don't think I need to implement a linked list since I'm not adding or removing elements very often.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不知在何时 2024-11-24 05:08:44

数组实际上是对属性进行特殊处理的对象,其名称是数组索引。

通过分配“null”,您可以使每个属性都存在,这将使用非零的内存量,并且如上所述会减慢查找速度。

您可以改为删除不存在的成员,这将导致稀疏数组:

var small = [a2, b2, c2,,,,,,, i2];
// small == [a2, b2, c2,undefined,undefined,undefined,undefined,undefined,undefined, i2]

编辑
请注意,如果您将未定义的值显式分配给数组元素(或任何变量),则它会占用空间。在这种情况下,要回收内存,您需要显式删除该元素。我的代码示例中显示的初始化样式从未将任何东西分配给省略的元素,因此它们根本不存在。这可以通过检查这些元素是否作为数组对象的属性存在来确认:

// continued from above
small.hasOwnProperty('3'); // returns false

small[3] = undefined;
small.hasOwnProperty('3'); // now returns true because the property exists

delete small[3];
small.hasOwnProperty('3'); // returns false again

alert(small.length); // alerts '10', showing that the array itself is still intact.

Arrays are actually Objects with special treatment of properties with names that are array indexes.

By assigning 'null', you bring each property into existence, which will use a non-zero amount of memory and as mentioned already slow down lookups.

You can elide the non-existent members instead, which will result in a sparse array:

var small = [a2, b2, c2,,,,,,, i2];
// small == [a2, b2, c2,undefined,undefined,undefined,undefined,undefined,undefined, i2]

Edit
Note that undefined does take space if you explicitly assign it to an array element (or any variable). To reclaim memory in this case, you will need to explicitly delete the element. The initialization style shown in my code sample never assigns anything to the elided elements, so they do not exist at all. This can be confirmed by checking for those elements' existence as properties of the array object:

// continued from above
small.hasOwnProperty('3'); // returns false

small[3] = undefined;
small.hasOwnProperty('3'); // now returns true because the property exists

delete small[3];
small.hasOwnProperty('3'); // returns false again

alert(small.length); // alerts '10', showing that the array itself is still intact.
飘过的浮云 2024-11-24 05:08:44

为什么不把小项目放入large[2].small?无论如何,你通常不必担心 javascript 中的内存消耗,但最好还是将未使用的位置保留在小的未定义中(这比将它们设置为未定义更重要!),以便 javascript 引擎可以决定切换稀疏数组(用哈希表而不是数组表示)。

Why not just put the small items into large[2].small? Anyway, you usually don't have to worry about memory consumption in javascript, but still it is better to leave the unused positions in small undefined (which is something else than setting them to undefined!), so that javascript engine can decide to switch to sparse array (represented by a hashtable instead of an array).

世界如花海般美丽 2024-11-24 05:08:44

Null 只会消耗单词 'NULL' 大小的内存(就解释器而言),但查找速度会变慢,因为数组中充满了不会转到查找结果的对象,而 JS 没有方法来优化这个。
您应该更好地使用对象数组,并且每个对象都应该保留一个值和索引。

undefined 的使用也很棘手。就解释和脚本大小而言,这会增加内存,但这不是规范的一部分来建议 undefined 是否应该消耗内存以及消耗多少内存,因此这取决于浏览器,他的垃圾收集设施,消耗内存堆ETC。
也许最好的方法就是尝试。在 Chrome 中运行相对较大的 NULL 和未定义数组,拍摄堆快照并进行比较。

Null will consume the memory only for the size of a word 'NULL' (in terms of interpreter), but the lookup will slow down because of the array overwhelmed with objects which will not go to the lookup result, and JS does not have a way to optimize this.
You should better use the array of objects, and each object should keep a value and the index.

Usage of undefined is tricky as well. In terms of interpretation and script size, this will increase a memory, but this is not a part of specs to advise whether undefined should consume memory and how much, so it is up to a browser, his facilities to garbage collect, consume memory heap etc.
The best way to go is to try, probably. Run a relatively large array of both NULLs and undefined's within Chrome, take a heap snapshot and compare.

失退 2024-11-24 05:08:44

我无法完全回答您的问题,因为我不确定 null 是否占用与显式将其设置为 undefined 一样多的空间。但我相信执行此操作的标准方法是使用 Array 构造函数:

var large = [1,2,3,4,5,6,7];
var small = new Array(large.length);
small.length; // 7
small[0]; // undefined

我相信这比显式将值设置为 undefined 使用的内存更少,但效果是相同的。我已将其用于具有 250,000 多个索引的稀疏数组,并且没有遇到任何内存问题(使用 Google Chrome)。

编辑:(在尝试并做了更多研究之后)很多人不喜欢 new Array() 构造函数,原因有很多(参见例如 此讨论)。但我认为它对于大型稀疏数组有几个优点:

  • 它正确设置了 length 属性。如果您需要数组长度与大数组匹配,则在不显式设置(small.length = large.length)或在末尾放置未定义的内容(Small[large.length-1] = undefined)。

  • 它不会为空索引设置键,这让我相信它使用更少的内存。如果您有一个数组 a = [null,null,null]a = [undefined,undefined,undefined],这些数组每个都有三个索引,并且如果您使用a.mapa.forEach 您的函数将为每个索引调用。如果您使用a = new Array(3),然后调用a.forEach,则您的函数将被您已指定的索引调用显式设置为构造后的值。

之间似乎并没有太大的性能差异

var a = new Array(2000); 
a[2000] = 1;

但是:和:

var = [];
a[2000] = 1;

为您提供了一个长度为 2000 且只有一个定义的索引的数组。因此,如果您不关心 smalllength 是否与 largelength 匹配,我只需使用 var a = [] 并根据需要动态调整其大小 - 从设置和获取特定索引值的简单角度来看,它是完全相同的。

I can't fully answer your question, because I'm not sure whether null takes up as much room as explicitly setting it to undefined. But I believe the standard way to do this is to use the Array constructor:

var large = [1,2,3,4,5,6,7];
var small = new Array(large.length);
small.length; // 7
small[0]; // undefined

I believe this uses less memory than explicitly setting values to undefined, though the effect is the same. I've used this for a sparse array with 250,000+ indices, and didn't experience any memory issues (using Google Chrome).

Edit: (after playing around and doing a little more research) Lots of folks don't like the new Array() constructor, for lots of reasons (see e.g. this discussion). But I think it has a couple of advantages for large, sparse arrays:

  • It sets the length property properly. If you need the array length to match your large array, you can't do this otherwise without setting it explicitly (small.length = large.length) or putting something undefined at the end (small[large.length-1] = undefined).

  • It doesn't set keys for empty indices, which leads me to believe it uses less memory. If you have an array a = [null,null,null] or a = [undefined,undefined,undefined], those arrays each have three indices, and if you use a.map or a.forEach your function will be called for each index. If you use a = new Array(3) and then call a.forEach, your function will only be called for the indices you've explicitly set to a value post-construction.

But there doesn't seem to be a big performance difference between:

var a = new Array(2000); 
a[2000] = 1;

and:

var = [];
a[2000] = 1;

which also gives you an array of length 2000 with only one defined index. So if you don't care whether the length of small matches the length of large, I'd just use var a = [] and have it resized dynamically as necessary - from the simple perspective of setting and getting values at specific indices, it's exactly the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文