0

I'm in a discussion with a co-worker concerning the use of structs. I have a couple of structs that contain several static properties that are used throughout our website. The value of those properties are all strings. They're not very long, the longest value has 29 characters.

His argument: "I am saying there is no performance gain because there are strings inside of them. For value types yes you gain memory/gc benefits. With strings they are ref types so allocate to the heap and won't give any benefit."

My argument: "...I'm simply treating the string values as value types by using the struct, therefore saving time and gaining performance by not having to instantiate it every time."

Here is an example of one of the structs so that you can see how I'm using them:

public struct Hero
{
    public static string Image          = "Hero Image";
    public static string Eyebrow        = "Hero Eyebrow";
    public static string Heading        = "Hero Heading";
    public static string Subheading     = "Hero Subheading";
    public static string YoutubeLink    = "Youtube Hero Link";
    public static string PardotForm     = "Pardot Form Hero Link";
    public static string PardotDirect   = "Pardot Direct Hero Link";
    public static string DirectLink     = "Direct Hero Link";
    public static string FacebookLink   = "Hero Facebook Link";
    public static string TwitterLink    = "Hero Twitter Link";
    public static string LinkedInLink   = "Hero LinkedIn Link";
    public static string LinkClassNames = "Class Names";
}

Let me know if I'm completely wrong and should just use classes or if there is a better way of using the structs for my values (i.e: readonly instead of static, etc...).

5
  • 9
    What does a struct have to do with this? Statics don't much care if they're in a struct or not. Though... you probably want to make these const or at least readonly to prevent someone rewriting your globals :P
    – Telastyn
    Commented Jan 22, 2019 at 21:27
  • 2
    ....and of course I immediately think "But shouldn't some of those be runtime properties, not compile-time properties?". Once you start including things like "Facebook", "Twitter", and "LinkedIn", I get suspicious that there might be a more maintainable way of doing things.... Commented Jan 22, 2019 at 21:51
  • 1
    I think there is a good argument for strings shouldn't be in the code at all but in some resource file, for C# i tend to use the standard settings file
    – jk.
    Commented Jan 23, 2019 at 13:02
  • 4
    "there is no performance gain", "saving time and gaining performance" -- these are testable assertions, except that you haven't answered performance compared to what? This is like asking "Does a 2017 Camaro have better performance?" Well, better performance than what? I'm not seeing the alternative here. If you have two pieces of code and an argument about which is faster, just test it.
    – trent
    Commented Dec 21, 2020 at 14:51
  • OP has some misconceptions about how things work at the lower-level in C#. Perhaps clarifying those misconceptions would have answered (or "resolved without answering") OP's questions.
    – rwong
    Commented Dec 21, 2020 at 22:30

4 Answers 4

10

I'll assess what you both said:

  • For value types yes you gain memory/gc benefits.

    True.

  • With strings they are ref types so allocate to the heap and won't give any benefit.

    True.

  • ..I'm simply treating the string values as value types by using the struct

    This doesn't make sense. You can't "treat" as value types or reference types. That's determined by how String is implemented. Given that String is read-only and un-subclassible in most programming languages, it usually has value semantics (even if it is really implemented as a reference to a heap object)

  • therefore saving time and gaining performance by not having to instantiate it every time.

    The struct doesn't matter here. String constants are in a static portion of the program, they're not subject to garbage collection, and they're not on the heap.

  • and gaining performance by not having to instantiate it every time.

    Access a static variable on a type doesn't instantiate the type, regardless of whether it's a struct or class.

Putting these strings in struct vs. a class doesn't matter. As long as they're string constants, they're lazily initialized the first time the struct/class is references.

9
  • 1
    Don't know about C# but in Java constant strings (Java final) are actually inlined so often the class containing them isn't even loaded. (Also makes for some extra funky things that can happen with reflection if you are not careful) Commented Jan 22, 2019 at 22:48
  • 1
    @Hangman4358 Thats correct in C# aswell, but these arent declared as const, the values are all calculated at runtime
    – richzilla
    Commented Jan 23, 2019 at 8:50
  • When you say strings are not on the heap and not subject to garbage collection, this is not correct. You are confused between constant strings (which are interned to a static table in the program) and dynamic/runtime created strings (which ARE created on the heap and subject to GC). I have debugged many a memory dump for apps with memory problems caused by inefficient string creation.
    – Dave Black
    Commented Oct 20, 2023 at 21:15
  • @DaveBlack Hmm? I was specifically talking about string constants.
    – Alexander
    Commented Oct 20, 2023 at 21:54
  • You were describing the behavior of constant (compile time) strings. This is very different than runtime behavior of dynamic string creation. Strings are immutable and any change to a string creates a new one.
    – Dave Black
    Commented Oct 22, 2023 at 18:35
3

His argument: "I am saying there is no performance gain because there are strings inside of them. For value types yes you gain memory/gc benefits. With strings they are ref types so allocate to the heap and won't give any benefit."

Your coworker is mostly correct.

To put the situation into simple terms:

  • It is the type of an object that determines whether it is a value type or a reference type. Every type is either a reference type or a value type. Unless you are the one creating the type, you do not get to choose which.
  • The built-in string type is, and always will be, a reference type. You cannot turn it into a value type through any means.
  • It is typically only local variables and parameters that provide the potential for value types to be more efficient. static member variables are stored differently and are not governed by quite the same rules.
  • It does not matter whether static fields are kept in a struct or a class because it does not affect how they are stored.

A more in-depth breakdown about the relationship between value types, reference types and storage can be found in this blog post.

The bottom line is that it's a lot more complicated than the usually recited mantra that 'value types go on the stack, reference types go on the heap'. Ultimately whether you chose to make something a struct or a class should depend more on other factors.

(See this other answer or this blog post for more details on choosing between struct and class.)

2
  • Swift strings are value types. So are arrays, dictionaries, and structs. The data itself is usually on the heap.
    – gnasher729
    Commented Apr 16, 2022 at 6:06
  • 3
    @gnasher729 The OP's question is tagged C#, not Swift. Thus what other languages do is largely irrelevant.
    – Pharap
    Commented Apr 16, 2022 at 6:37
2

strings in a struct as values to static properties

This is a head-splitting description. First, strings are always reference types, no matter how or where you declare them. Your struct will be empty because you have no non-static members. The references will take up 4 * 12 bytes in size. Where the characters are will no longer matter, they will remain in the same place for the lifetime of your process. If you want the text to be laid out in a struct you must use character arrays instead and declared them non-static.

Second, there are no properties in your example. You only have data members.

Performance-wise you gain nothing by having strings contained in a struct. You may even lose performance if you are not careful by cause boxing and unboxing.

Either way, for accessing the strings it would not bear significance. Reading a string of only a couple of characters will already take longer than finding the first character, which is really what this is about. And this ratio will quickly increase as the string gets longer.

4
  • 1
    "Your struct will be 4 * 12 bytes in size" -> No it won't, because these are static fields.
    – Alexander
    Commented Jan 22, 2019 at 22:23
  • "You may even lose performance if you are not careful by cause boxing and unboxing." There's no boxing/unboxing going on, because there are no struct instances
    – Alexander
    Commented Jan 22, 2019 at 22:24
  • @Alexander We do not know if he has struct instances or not, for all we know he may create an instance and pass that Hero around as an argument to a method as a ref parameter. The struct itself is not declared static. I realize you are right with your first comment, I will edit. Commented Jan 22, 2019 at 22:35
  • I don't create instances of my structs I access them directly wherever needed and I never see the need to use them as ref parameters. Commented Jan 23, 2019 at 14:12
-3

Neither one of you bothered to benchmark your claims, so performance becomes a moot point.

Your suggestion of a struct in this case is therefore wrong, because it is a deviation from the norm, which would be a static class with const strings. The time a maintenance developer spends wondering why this code is a struct instead of a class is going to dwarf the performance you may or may not gain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.