35

In each project we have there is a file used to store the various SQL statements used in that project. There are a handful of variations on how the class is declared and how the strings are declared.

Example class declartions:

internal sealed class ClassName
internal static class ClassName
public sealed class ClassName
public static class ClassName
internal class ClassName

Example string declarations:

internal const string stringName
internal static string stringName
public static readonly string stringName
public static string stringName
public const string stringName

I don't understand what the performance implications are between the different declarations. Is there a best practice for this situation/scenario?

Ryan Rodemoyer
  • 5,548
  • 12
  • 44
  • 54

5 Answers5

86

I don't understand what the performance implications are between the different declarations

The cost of evaluating the database query is probably going to be millions or billions of times the cost difference of changing from a constant to a readonly field or vice versa. Don't even worry about performance of something that takes a couple of nanoseconds when you have database operations that have latency measured in milliseconds.

What you should be worrying about is semantics, not performance. The question boils down to "readonly, constant or neither?"

Get the semantics right. A "readonly" field means "this field changes exactly once per time this program is executed", from null to its value. A "const" field means "this value never changes, not now, not in the next version, not ever, it is constant for all time." An ordinary field can change value at any time.

A readonly field is something like a version number. It changes over time, but does not change over the execution of the program. A constant is something like pi, or the atomic number of lead; it is fixed, eternal, never changes. An ordinary field is good for something that changes over the course of the program, like the price of gold. Which is your query like? Will it be constant throughout the course of this program, constant for all time, or not constant at all?

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 10
    +1 for "What you should be worrying about is semantics, not performance" – Dan Esparza Jun 26 '12 at 17:37
  • 1
    Besides the semantic meanings of each, is there any particular benefit to use `const` over `static readonly`? My understanding is that `static readonly` can do what `const` does and even more (such as dynamic initialization). If disregarding semantics, why would one choose `const` over `static readonly`? – Nicholas Miller Apr 02 '15 at 13:04
  • @NickMiller: This is a question-and-answer site; that sounds like a pretty good candidate for a question. Even better if you could give a specific example of code where you are trying to decide which is more appropriate. – Eric Lippert Apr 02 '15 at 16:03
9

You should choose an access modifier (public or internal) based on which code uses the strings.

  • static const is a compiler error.

  • A static readonly field is a normal field which cannot be set after the static ctor.

  • A const string will be replaced by its literal value at compile time.
    Therefore, it will give slightly better performance (since the runtime doesn't use the field).
    However, since it's substituted at compile-time, any changes to the definition in one assembly will not be picked up by other assemblies until they're all recompiled.

If your code is only used in one assembly, you might as well use const strings.
However, if your strings are used by other assemblies (or might be in the future), you should use static readonly strings for maintainability.

Also note that a const string is a compile-time constant.
If you need to incldue things like the machine name or username in the string, you need to make it static readonly.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Explanation of why `static const` is a compiler error: [Don't Repeat Yourself](https://learn.microsoft.com/en-us/archive/blogs/ericlippert/dont-repeat-yourself-consts-are-already-static) by Eric Lippert – Brian Aug 19 '20 at 21:42
7

On const vs static readonly:
const can have better performance since it's a compiletime constant
But on the other hand it has problems with binary versioning. The constant gets inlined into the assembly that uses it, so if the assembly that declares it gets changed the other assembly needs to be recompiled or it will use an outdated constant.

For structs I typically use a static property instead of a readonly field, since the jitter can optimize it, but I still don't have versioning problems.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • "instead of a readonly field,, since the jitter can optimize it" - but with a readonly field, there's less optimization needed in the first place – Tim Robinson Dec 09 '10 at 20:30
  • A readonly field can't be optimized at all because it's a variable, whereas a property that returns a struct can become a constant as far as the jitter is concerned and thus can be optimized. I used that when implementing my own fixed-point type. – CodesInChaos Dec 09 '10 at 20:54
  • @CodeInChaos: "The constant gets inlined into the assembly that uses it..." Really? For value types, I agree. But certainly not strings! – Jim Mischel Dec 09 '10 at 21:32
  • Ok could be that it's not inlined for strings. Did you test it? Google turned up this: http://www.tek-tips.com/faqs.cfm?fid=6346 but of course it's not authoritative. – CodesInChaos Dec 09 '10 at 21:43
  • @CodeInChaos: I stand corrected. You're right and I'm very surprised by the compiler/runtime behavior in this regard. See http://blog.mischel.com/2010/12/10/how-constant-is-a-constant/ – Jim Mischel Dec 10 '10 at 23:29
  • Thanks for testing it. I wasn't 100% sure either. – CodesInChaos Dec 11 '10 at 10:30
3

Speedwise the difference between public static string and public const string is negligible.

In IL it's a difference between

ldsfld someaddr.field 

and

ldstr "your const here"

Here lies the answer though. By using const you're literally make your assembly to use that literal every time you use it, so the assembly will be ridden with those literals. With static the will be "pointers" to the central location.

The biggest gotcha lies in the following: you can't perfrom switch case against static strings, but you can against const (as you should).

So, my take on this: if you need to use switch - you have to use use const; if you don't - I'd prolly go with static.

HTH

Nikolai

DarthSLR
  • 41
  • 1
  • 5
0

Given that you're using Visual Studio, a small benefit for using public const over public static readonly is the ability to use IntelliSense to "peak" at the const value.

e.g. Given:

public class Constants
{
     public const string ConstString = "Visible!";
     public static readonly string StaticReadonlyString = "Invisible!";
}

hovering over a string that's a constant hovering over a string variable that's static readonly

Michael Johnston
  • 2,364
  • 2
  • 27
  • 48