但是,如果您尝试通过查看IL代码进行钻取,那么您只能看到魔术单词“Box”.
推测,我猜这个运行时有一些基于泛型的秘密类,就像Box< T>与一个公共T值属性,拳击一个int将看起来像:
int i = 5; Box<int> Box = new Box<int>; Box.Value = 5;
打开int将会便宜得多:return Box.Value;
不幸的是,我的性能饥饿的服务器应用程序做了一个很好的拳击,特别是小数点.更糟糕的是,这些盒子是短命的,这使我怀疑我付两次,一次用于实验盒子,然后在完成它之后再次收集垃圾.
如果我自己正在同这个记忆,我会考虑在这里使用一个对象池.但是,由于实际的对象创建被隐藏在IL中的一个魔术词之后,我的选择是什么?
我的具体问题:
>是否有一个现有的机制来诱使运行时从池中取出盒子,而不是使其运行?
>在拳击期间创建的实例的类型是什么?是否可以手动控制拳击过程,但仍然可以与拆箱兼容?
如果最后一个问题似乎很奇怪,我的意思是我可以创建我自己的Box< T>或DecimalBox类,手动池,和框/ unBox手动.但是我不想去修改代码中消耗盒装值的各个地方(也称为unBox吧).
解决方法
Speculating,I guess that the runtime has some sort of generics-based secret class up its sleeve
你的猜测是对的.在逻辑上你可以将一个盒子看成是一个魔法盒子< T>类型的行为与您所描述的(具有几点魔法;例如,可空值类型框的方式有点不寻常.)作为实际的实现细节,运行时不会使用泛型类型.拳击存在于CLR v1中,在通用类型被添加到类型系统之前.
my performance-hungry server application does a fair bit of Boxing,specifically of decimals.
如果在这样做的时候疼痛,那么停止这样做.而不是试图使拳击更便宜,停止这样做首先.你为什么要装一个小数点?
Worse,these Boxes are short-lived,which makes me suspect I pay twice,once for instanciating the Box and then again for garbage collecting the Box after I’m done with it.
短命比长寿更好;你付出的短命的堆物体收集他们一次,然后他们死了.使用长寿命的堆对象,您可以一次又一次地支付成本,因为对象继续生存.
当然,您对短期物品可能担心的成本并不是收集本身的成本.相反,它是收集压力;分配的更多短命的对象等于更频繁的垃圾收集.
分配成本非常小.在GC堆上移动指针,将小数位复制到该位置,完成.
If I was alloacting this memory myself,I would consider the use of an object pool here.
对;您支付更多的收集长寿命对象的成本,但是由于收集压力较小,您收集的集合较少.那可以是一场胜利.
Is there an existing mechanism for inducing the runtime to take Boxes from a pool rather than instanciating them?
不.
What is the type of the instance created during Boxing? Is it possible to manually take control of the Boxing process,yet still be compatible with unBoxing?
盒子的类型是被盒子的东西的类型.通过调用GetType来询问它;它会告诉你盒子是神奇的;它们是它们包含的东西的类型.
就像我之前说过的,而不是试图使拳击更便宜,只是不要这样做.