C # string and Flyweight Mode

Source: Internet
Author: User
Document directory
  • Flyweight Mode
  • The string in C # is not in the Flyweight mode.
  • String and Flyweight modes in C #
  • More Thoughts

I wrote this article mainly because there are many misunderstandings about the C # string and the metadata mode on the Internet.

Flyweight Mode

Let's talk about this name first. fly is a fly. Yes, it does not mean fly. It means fly. We all know that weight is the weight of a fly, is very light. Therefore, the Flyweight mode is a very lightweight object.

The objective of Flyweight is to solve the memory consumption problem of a large number of fine-grained objects. Of course, it is difficult to create a memory in any mode or method, therefore, the metadata mode is applicable to repeated data in these fine-grained objects.

Flyweight divides the object state (usually represented by attributes) into two parts: Internal State and external State. Internal status External states are not repeated (or necessary ), External status
The internal status is easy to repeat. Therefore, Flyweight extracts external States for sharing, which solves the memory usage problem to a certain extent.

The string in C # is not in the Flyweight mode.

On the Internet, you can often see a saying that the string in C # uses the Flyweight mode, which is incorrect.

Where is the error? According to the above introduction, the error occurs when the string does not have the so-called" Internal status External status ".

Generally, the reason why the string is a Meta is the following code:

String a = "Hello World ";
Console. WriteLine (Object. ReferenceEquals (a, "Hello World"); // True

When you use a string to directly count, no matter how many "Hello World" you write, there is only one string object in the memory.

The string created during running is not in this column. You can use some methods to force new strings to be generated in the memory.

String a = "Hello World ";
Console. WriteLine (Object. ReferenceEquals (a, new String ("Hello World". ToCharArray (); // False

Because we forcibly call new, the object corresponding to the direct amount of "Hello World" in the memory is not the same.

Interestingly, C # also allows you to forcibly Add a string to the string pool (if it already exists, it will only be found.

String a = "Hello World ";
String B = String. Intern (new String ("Hello World". ToCharArray ()));
Console. WriteLine (Object. ReferenceEquals (a, B ));

Or

String a = String. Intern (new String ("Hello World". ToCharArray ()));
String B = String. Intern (new String ("Hello World". ToCharArray ()));
Console. WriteLine (Object. ReferenceEquals (a, B ));

As mentioned above, this behavior is different from the internal state and external State used by Flyweight. Two objects are actually the same object.

String and Flyweight modes in C #

Well, I have mentioned a lot before. The string in C # is not in the Flyweight mode, but does it mean that the string in C # has nothing to do with Flyweight?

Of course not. Otherwise, it would be too painful for me to write such an article ......

The string pool and the Intern method are just the artifacts to implement Flyweight!

Consider that we have a certain type of object, which may create millions of objects. The object happens to have such an attribute called color, which is randomly generated during object construction. The color uses the rgb color, it is represented by rgb24, so the color string is similar to # ccc.

The code is written as follows:

    class Element    {static Random rnd = new Random();static char[] table;static Element() {    table = "0123456789abcdef".ToCharArray();}public string color;public Element(){    color = "" + table[rnd.Next() % 16] + table[rnd.Next() % 16] + table[rnd.Next() % 16];}    }

Next we will create 10 million objects to see how

    Element[] eles = new Element[30000000];    for (var i = 0; i < 30000000; i++)    {eles[i] = new Element();    }

The task manager shows that a large part of memory has been eaten.

Next we use String. Intern to implement Flyweight:

    class Element    {static Random rnd = new Random();static char[] table;static Element() {    table = "0123456789abcdef".ToCharArray();}public string color;public Element(){    color = String.Intern("" + table[rnd.Next() % 16] + table[rnd.Next() % 16] + table[rnd.Next() % 16]);}    }

Let's also look at the running results:


We can see a significant change in memory usage.

Because the properties of the String object cannot be changed, the String. after Intern, we can't see the difference between the front and back colors. That is to say, the Element class before and after modification is completely equivalent, but Flyweight saves us a lot of memory.

More Thoughts

This typical flyweight scenario reveals the benefits External status Internal state features: objects that cannot be changed like strings. The same is true for the font object Glyph in the example of the GoF original book.

The implementation of flyweight in the String. Intern Object pool is also worth learning from. We can consider using a similar method when designing an external State object of flyweight.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.