简体   繁体   English

Class自动属性的内存分配

[英]Memory allocation of a Class auto properties

I have a class with multiple properties. 我有一个具有多个属性的类。 For example 例如

public class Customer
    {
        public int id { get; set; }
        public string abc{ get; set; }
        public bool abcd { get; set; }
        public string abcde { get; set; }
        public string abcdef { get; set; }
        public string abcdefg { get; set; }
        public string abcdefgh { get; set; }
        public string xyz { get; set; }     
    }

Now I want to know how much memory space is consumed by the get set properties. 现在,我想知道get set属性消耗了多少内存空间。 I only require few of the properties in one of my API call and all of these properties for another API call. 在一个API调用中,我只需要几个属性,而在另一个API调用中,则需要所有这些属性。 So I want to know whether I should create two different classes and use them for my separate API calls or just use one common class with multiple get set properties and use it for my API calls. 因此,我想知道是否应该创建两个不同的类,并将其用于单独的API调用,还是仅使用具有多个get set属性的一个公共类,并将其用于我的API调用。 Any guidance will be much appreciated. 任何指导将不胜感激。 Thanks 谢谢

the int and bool will typically be packed together into 8 bytes; 通常将intbool打包成8个字节; the string references take 4 (32-bit) or 8 (64-bits) for the references. string引用采用4(32位)或8(64位)作为引用。 If the strings have non-null values , then that space will be allocated separately and will be whatever the string needs. 如果字符串具有非null值 ,则将单独分配该空间,该空间将是字符串所需的任何空间。

But frankly: unless you're allocating millions of them, splitting it into 2 different types won't save you anything real - it will just be yak shaving. 但坦率地说:除非您要分配数百万个 ,否则将其拆分为2种不同的类型将不会为您节省任何实际费用 -简直就是sha牛。 Especially for the scenario where the strings are null . 特别是对于字符串为null

We have to exclude the string. 我们必须排除字符串。 This one can be anywhere from "null" to "whatever Max Lenght for string was today". 这个范围可以从“空”到“今天的最大长度”。

Theoretically a Autoimplement Property should cost as much as a minimal, manual property: One backing field. 理论上,“自动实现”属性的成本应与最小的手动属性相同:一个后备字段。 One get and one set function for the entire type. 一键通一集功能。 The single most important rule about properties is to not accidentally access the backing field in class code. 关于属性的最重要的单个规则是不要意外地访问类代码中的后备字段。 And Autoimplement Properties do that, by simply not giving the Backing Field a name you could use. 通过简单地不给Backing Field一个可以使用的名称,Autoimplement Properties就可以做到这一点。 It is still there. 它仍然在那里。 It propably has a name derived from the Property name for Reflection. 它可能具有一个从“反射”的“属性”名称派生的名称。 But your code has no realy way to access it. 但是您的代码没有真正的方法来访问它。

Theoreitically, because now coems in the JiT. 从理论上讲,因为现在是JiT。 The JiT can do a lot of Optimisations: JiT可以进行很多优化:

  • Those Automatic accessors are very little code. 那些自动访问器是很少的代码。 So there is a decent chance that the cost of Inlining them is below the cost of calling them. 因此,有很大的机会使它们内联的成本低于调用它们的成本。 So I give it a 90% chance the JiT will inline those. 因此,我给了JiT 90%的机会来内联这些代码。
  • If you create a temporary variable to use it the next line, this one might run into DeadCode detection. 如果创建一个临时变量以在下一行使用它,则该变量可能会遇到DeadCode检测。 Wich means it will be cut out and replaced by the originall access. Wich表示将其剪下并替换为原始访问。
  • But of coruse it goes the other way too. 但是,顺带一提,它的发展方向也相反。 In order to get around the overhead inherent in ArrayBounds Checks, the JiT might detect "redundant Acesses" with teh same Index and create a temporary variable to use. 为了解决ArrayBounds Checks固有的开销,JiT可能会检测具有相同Index的“冗余访问”并创建一个临时变量来使用。

While I have not read about it yet, I would not rule out that the JiT can even cut unused properties from classes. 虽然我还没有读过它,但我不排除JiT甚至可以从类中删除未使用的属性。 It is all just runtime optimisations. 仅仅是运行时的优化。 It at least can cut unaccessed varriables (and their initialsiation) out as dead code. 它至少可以将未访问的变量(及其初始化)切掉为无效代码。 As I found out when I tried forcing a 2 GiB OOM: 当我尝试强制使用2 GiB OOM时发现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OOM_32_forced
{
    class Program
    {
        static void Main(string[] args)
        {
            //each short is 2 byte big, Int32.MaxValue is 2^31.
            //So this will require a bit above 2^32 byte, or 2 GiB
            short[] Array = new short[Int32.MaxValue];

            /*need to actually access that array
            Otherwise JIT compiler and optimisations will just skip
            the array definition and creation */
            foreach (short value in Array)
                Console.WriteLine(value);
        }
    }
}

I agree that this is Micro Optimisations. 我同意这是微观优化。 But even more, those might be ones the JiT can do for you already . 但更重要的,这些可能是那些在JIT可以为你已经这样做 So you might save nothing at all. 因此,您可能一无所有。 Personally I prefer read- and debugability of code way before such Optimisations. 就我个人而言,在进行此类优化之前,我更喜欢代码的可读性和可调试性。 I can often do something "ineffective" because I can rest in the knowledge the JiT will propably deal with it. 我经常可以做一些“无效”的事情,因为我可以依靠JiT会适当地处理它的知识。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM