装箱的值是对原始类型*进行最小包装的数据结构。装箱的值通常存储为指向堆上对象的指针。
因此,盒装值使用更多的内存,并且至少要进行两次内存查找才能访问:一次获取指针,另一次跟随该指针到达原语。显然,这不是您想要在内部循环中执行的 *** 作。另一方面,带框值通常会与系统中的其他类型一起使用。由于它们是该语言中的一流数据结构,因此它们具有其他数据结构所期望的元数据和结构。
在Java和Haskell中,泛型集合不能包含未装箱的值。.NET中的泛型集合可以保存未装箱的值,而不会受到惩罚。在Java的泛型仅用于编译时类型检查的情况下,.NET将为在运行时实例化的每种泛型类型生成特定的类。
Java和Haskell具有拆箱数组,但是它们明显不如其他集合方便。但是,当需要最佳性能时,避免装箱和拆箱的开销值得一点不便。
*在此讨论中,原始值是可以存储在调用堆栈中的任何值,而不是作为指向堆上值的指针存储的值。通常,这只是机器类型(整数,浮点数等),结构,有时还有静态大小的数组。.NET-land将它们称为值类型(与引用类型相对)。Java人士称它们为原始类型。Haskellions只是称它们为未装箱。
在这个答案中,我还将重点放在Java,Haskell和C#上,因为这就是我所知道的。值得一说的是,Python,Ruby和Javascript都具有专门装箱的值。这也称为“一切都是对象”方法*。
***警告:在某些情况下,足够高级的编译器/ JIT实际上可以检测到在查看源代码时在语义上装箱的值可以在运行时安全地成为未装箱的值。本质上,由于出色的语言实现者,您的盒子有时是免费的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)