将项目添加到列表/ 防御性编程
在添加到 C# 列表时明确检查/处理没有达到 2^31 - 1 (?) 最大条目数是疯狂的,是真是假?
(假设这是一个平均列表大小小于 100 的应用程序。)
Explicitly checking/handling that you don't hit the 2^31 - 1 (?) maximum number of entries when adding to a C# List is crazyness, true of false?
(Assuming this is an app where the average List size is less than a 100.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
1. 内存限制
那么,没有任何属性的 System.Object 的大小为 8 个字节(2x32 位指针),或者在 64 位系统中为 16 个字节。 [编辑:]实际上,我刚刚在WinDbg中检查过,x86(32位)上的大小是12字节。
因此,在 32 位系统中,您需要 24Gb 内存(在 32 位系统上则没有)。
2. 程序设计
我坚信,这么大的列表不应该保存在内存中,而应该保存在其他存储介质中。 但在这种情况下,您始终可以选择创建一个包装列表的缓存类,该类将在后台处理实际存储。 因此,在添加之前测试大小是进行测试的错误位置,如果有一天您发现有必要,您的 List 实现应该自行执行。
3. 为了安全起见
为什么不在每个方法中添加一个重入计数器来防止堆栈溢出? :)
所以,是的,对此进行测试是疯狂的。 :)
1. Memory limits
Well, size of System.Object without any properties is 8 bytes (2x32 bit pointers), or 16 bytes in 64-bit system. [EDIT:] Actually, I just checked in WinDbg, and the size is 12bytes on x86 (32-bit).
So in a 32-bit system, you would need 24Gb ram (which you cannot have on a 32-bit system).
2. Program design
I strongly believe that such a large list shouldn't be held in memory, but rather in some other storage medium. But in that case, you will always have the option to create a cached class wrapping a List, which would handle actual storage under the hood. So testing the size before adding is the wrong place to do the testing, your List implementation should do it itself if you find it necessary one day.
3. To be on the safe side
Why not add a re-entrance counter inside each method to prevent a Stack Overflow? :)
So, yes, it's crazy to test for that. :)
看起来太过分了。 您是否会首先根据列表中对象的大小达到机器的内存限制? (我假设此检查是由 List 类的用户执行的,并且在实现中没有任何检查?)
也许同事们正在提前思考,这让人放心? (讽刺!)
Seems excessive. Would you not hit the machine's memory limit first, depending on the size of the objects in your list ? (I assume this check is performed by the user of the List class, and is not any check in the implementation?)
Perhaps it's reassuring that colleagues are thinking ahead though ? (sarcasm!)
看起来是这样,我可能不会包括支票,但我对此感到矛盾。 程序员曾经认为 2 位数字足以代表日期字段中的年份,因为这对于代码的预期寿命来说是没问题的,但是我们发现这种假设是不正确的。
看看风险,看看努力并做出判断(也称为有根据的猜测!:-))。 我不会说这方面有任何硬性或快速的规则。
It would seem so, and I probably wouldn't include the check but I'm conflicted on this. Programmers once though that 2 digits were enough to represent the year in date fields on the grounds that it was fine for the expected life of their code, however we discovered that this assumption wasn't correct.
Look at the risk, look at the effort and make a judgement call (otherwise known as an educated guess! :-) ). I wouldn't say there's any hard or fast rule on this one.
正如上面的答案所示,我怀疑会出现更多问题,而不是担心这一点。 但是,如果您有时间和意愿,您可以打磨代码直到它大放异彩!
As in the answer above there would more things going wrong I suspect than to worry about that. But yes if you have the time and inclination that you can polish code till it shines!
是的
(你问的是真还是假..)
True
(well you asked true or false..)
刚刚尝试了这段代码:
我得到了 System.OutOfMemoryException。 那么你会做什么来检查/处理这个问题呢?
Just tried this code:
I got a System.OutOfMemoryException. So what would you do to check / handle this?
如果您不断向列表中添加项目,那么在达到该限制之前,您就会耗尽内存。 我所说的“长”实际上是指“比你想象的要早得多”。
请参阅此讨论对象堆(LOB)。 一旦达到大约 21500 个元素(64 位系统上的一半)(假设您存储对象引用),您的列表将开始成为一个大对象。 由于 LOB 的压缩方式与普通 .NET 堆不同,因此最终会严重碎片化,以致无法分配足够大的连续内存区域。
因此您根本不必检查该限制,它不是真正的限制。
If you keep adding items to the list, you'll run out of memory long before you hit that limit. By "long" I really mean "a lot sooner than you think".
See this discussion on the large object heap (LOB). Once you hit around 21500 elements (half that on a 64-bit system) (assuming you're storing object references), your list will start to be a large object. Since the LOB isn't compacted in the same way the normal .NET heaps are, you'll eventually fragment it badly enough that a large enough continous memory area cannot be allocated.
So you don't have to check for that limit at all, it's not a real limit.
是的,这就是疯狂。
考虑一下当您开始达到这些数字时,其余代码会发生什么情况。 如果列表中有数百万个项目,该应用程序是否可用?
如果应用程序有可能达到这么大的数据量,也许您应该采取措施来防止列表变得那么大。 也许您甚至不应该一次将所有数据保存在内存中。 我真的无法想象任何代码实际上都可以利用这么多数据的场景。
Yes, that is crazyness.
Consider what happens to the rest of the code when you start to reach those numbers. Is the application even usable if you would have millions of items in the list?
If it's even possible that the application would reach that amount of data, perhaps you should instead take measures to keep the list from getting that large. Perhaps you should not even keep all the data in memory at once. I can't really imagine a scenario where any code could practially make use of that much data.