6

Do const fields use less memory than regular variables?

JL.
  • 78,954
  • 126
  • 311
  • 459

1 Answers1

5

Const fields memory consumption depends on its usage. The values of const fields are embedded into the IL code during compilation. Without a single reference to a const field there is no memory consumed. When there are many references to the const field, then memory usage may multiply depending on the code portion currently residing in memory.

  • I'll take that as a yes, if the object gets instantiated multiple times. – JL. Nov 30 '09 at 11:00
  • 3
    This is quite a misleading answer. Constants *do not* "exist in one copy like static variables". In fact, whenever a `const` field is referenced in your code the compiler embeds the *value* of the constant in the generated IL. – LukeH Nov 30 '09 at 11:22
  • 2
    This means that if you have a large `const` field (ie, a string) that is referenced several times then it would probably use *more* memory than the equivalent `static` field. – LukeH Nov 30 '09 at 11:23
  • 6
    In practice you shouldn't usually worry about these micro-optimisations. If the field is a genuinely unchanging constant then use `const`; If it's not, don't. – LukeH Nov 30 '09 at 11:24
  • 3
    Luke, can you explain why multiple uses of a constant string would use up more memory? Are you in the habit of switching constant string interning off? – Eric Lippert Nov 30 '09 at 19:00
  • Eric, I just googled for "constant string interning" and stumbled upon your blog entry. http://blogs.msdn.com/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx While it's a fantastic explanation, I'm not sure if this optimization applies to consts. The const values are supposed to be embedded in code wherever they are referenced. You say that for strings this rules does not apply? –  Nov 30 '09 at 19:27
  • 4
    I'm not sure how to answer your question. Perhaps a list of facts will help. A constant string is represented in the generated code by a metadata token that gives an offset into the user string table. A metadata token is an integer. Using a constant string twenty times is exactly the same as using a constant integer twenty times; you use the same token over and over again. Strings in the user string table are interned. Do those facts answer your question? – Eric Lippert Nov 30 '09 at 21:32
  • Yes, they do, thank you. So through this technique the memory consumption is kept lower because only integers (of fixed and small size) are multiplied in code but not lengthy strings themselves. Is this the reason why strings are also accepted as const types though they're the only one of built-in types which do not have a fixed size? –  Nov 30 '09 at 21:50
  • 1
    Yes. Though a literal string is at runtime heap-allocated and a string in general does not have a fixed size, the bytes from which a particular constant string's initial value is copied are artefacts in the metadata itself that we can refer to by the offset into the string table; that offset, being an integer, is of constant size and is not heap allocated. – Eric Lippert Nov 30 '09 at 23:31
  • @Eric: Of course, you're right about `const` strings; it was a very poor choice of example. But the general principle still stands, doesn't it? If, for example, your code contains many references to a `const decimal` field then the generated IL will be larger than if that field was made `readonly` instead. – LukeH Dec 01 '09 at 12:05
  • Yes, for const decimals the generated IL is much larger. But decimals, not being a native type of the CLR, are often a special case. – Eric Lippert Dec 01 '09 at 15:20