什么是装箱和拆箱,需要进行哪些取舍? [英] What is boxing and unboxing and what are the trade offs?

查看:103
本文介绍了什么是装箱和拆箱,需要进行哪些取舍?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个清晰,简洁和准确的答案.

I'm looking for a clear, concise and accurate answer.

理想情况下,为实际答案,但欢迎提供良好解释的链接.

Ideally as the actual answer, although links to good explanations welcome.

推荐答案

带框的值为数据结构是围绕原始类型 *的最小包装.带框的值通常作为指向对象的指针存储在上.

Boxed values are data structures that are minimal wrappers around primitive types*. Boxed values are typically stored as pointers to objects on the heap.

因此,带框的值使用更多的内存,并且至少需要进行两次内存查找才能访问:一次获取指针,另一次跟随该指针指向基元.显然,这不是您想要在内部循环中执行的操作.另一方面,带框值通常在系统中的其他类型上发挥更好的作用.由于它们是该语言中的一流数据结构,因此它们具有其他数据结构所期望的元数据和结构.

Thus, boxed values use more memory and take at minimum two memory lookups to access: once to get the pointer, and another to follow that pointer to the primitive. Obviously this isn't the kind of thing you want in your inner loops. On the other hand, boxed values typically play better with other types in the system. Since they are first-class data structures in the language, they have the expected metadata and structure that other data structures have.

在Java和Haskell中,泛型集合不能包含未装箱的值. .NET中的泛型集合可以保存未装箱的值,而不会受到惩罚.在Java的泛型仅用于编译时类型检查的情况下,.NET将生成特定的类对于在运行时实例化的每种泛型类型.

In Java and Haskell generic collections can't contain unboxed values. Generic collections in .NET can hold unboxed values with no penalties. Where Java's generics are only used for compile-time type checking, .NET will generate specific classes for each generic type instantiated at run time.

Java和Haskell具有未装箱的数组,但是它们明显不如其他集合方便.但是,当需要最佳性能时,要避免装箱和拆箱的开销,这会带来一些不便.

Java and Haskell have unboxed arrays, but they're distinctly less convenient than the other collections. However, when peak performance is needed it's worth a little inconvenience to avoid the overhead of boxing and unboxing.

*在此讨论中,原始值是可以存储在调用堆栈上的任何值. ,而不是将其存储为指向堆上的值的指针.通常,这只是机器类型(整数,浮点数等),结构,有时还包括静态大小的数组. .NET-land将它们称为值类型(与引用类型相对). Java人士称它们为原始类型. Haskellions只是称它们为未装箱的.

* For this discussion, a primitive value is any that can be stored on the call stack, rather than stored as a pointer to a value on the heap. Frequently that's just the machine types (ints, floats, etc), structs, and sometimes static sized arrays. .NET-land calls them value types (as opposed to reference types). Java folks call them primitive types. Haskellions just call them unboxed.

**在这个答案中,我还将重点放在Java,Haskell和C#上,因为这就是我所知道的.值得一提的是,Python,Ruby和Javascript都具有专门装箱的值.这也称为一切都是对象"方法***.

** I'm also focusing on Java, Haskell, and C# in this answer, because that's what I know. For what it's worth, Python, Ruby, and Javascript all have exclusively boxed values. This is also known as the "Everything is an object" approach***.

***警告:足够高级的编译器/JIT在某些情况下实际上可以检测到在查看源代码时在语义上装箱的值可以在运行时安全地成为未装箱的值.本质上,由于使用了出色的语言实现程序,您的盒子有时是免费的.

*** Caveat: A sufficiently advanced compiler / JIT can in some cases actually detect that a value which is semantically boxed when looking at the source, can safely be an unboxed value at runtime. In essence, thanks to brilliant language implementors your boxes are sometimes free.

这篇关于什么是装箱和拆箱,需要进行哪些取舍?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆