How does CompilationRelaxations.NoStringInterning actually work?
Asked Answered
E

3

6

I am having problems demonstrating NoStringInterning

[assembly: System.Runtime.CompilerServices.CompilationRelaxations(System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterning)]

    class Program
    {
        static void Main(string[] args)
        {
            String s1 = "Friday";
            String s2 = "Friday";
            String s3 = "Friday";
            String s4 = "Friday";
            String s5 = "Friday";
            String s6 = "Friday";
            String s7 = "Friday";
            String s8 = "Friday";
            String s9 = "Friday";
            // etc...
            Console.WriteLine(Object.ReferenceEquals(s1, s2));
            Console.WriteLine(Object.ReferenceEquals(s1, s3));
            Console.WriteLine(Object.ReferenceEquals(s1, s4));
            Console.WriteLine(Object.ReferenceEquals(s1, s5));
            Console.WriteLine(Object.ReferenceEquals(s1, s6));
            Console.WriteLine(Object.ReferenceEquals(s1, s7));
            Console.WriteLine(Object.ReferenceEquals(s1, s8));
            Console.WriteLine(Object.ReferenceEquals(s1, s9));
            // etc...

I've tried with .NET CLR 2, 3, 4.. as output all I get is a bunch of True. I am expecting a bunch of False!

Etymon answered 24/3, 2013 at 17:50 Comment(0)
O
7

The documentation states that the attribute:

Marks an assembly as not requiring string-literal interning.

In other words, it does not prevent the compiler from doing string interning, just providing a hint that it is not required. The documentation is a little bit sparse in this area, but this also seems to be the conclusion in this MSDN forum post.

Overdevelop answered 24/3, 2013 at 18:1 Comment(2)
driis, if I look at IL DASM after compiling I see a bunch of lines with ldstr "Friday". You write "does not prevent the compiler from doing string interning" how is this related to the compiler? If the compiler was doing interning shouldn't there be only one ldstr "Friday" in the method? Why should I have to pay the price of loading this constant a bunch of times and having the runtime to sort out the duplicates? I'm confused...Etymon
I don't think ILDASM gives you the full story here. It's possible that the string only exists once in the #US heap, and the CLR instantiates one string object per string in the #US heap (instead of one per unique character sequence whith normal string interning). Since ILDASM replaces the #US heap references with the actual string literals I think you would need to use some lower level tool to see what's actually in there.Yocum
R
5

Not kick in an opened door, but clearly the attribute doesn't do what you think it does. Documentation for it is quite poor, both in MSDN and the CLI spec. The only thing that's obvious to me from its usage inside the CLR is that, when it is turned on, the compiler only has to ensure that identical strings are interned at the module level. This has a number of side effects that are relevant for inlining, ngen-ed and mixed-mode assemblies.

That would next force me explain the exact difference between modules and assemblies. Which I can't, modules are strange beasts that have no practical usage in common .NET programming. Best to forget that this attribute is relevant at all. Unless you have a custom build system that runs the C# compiler with the /target:module option, the C# compiler always interns at the assembly level so your test will always produce "true".

Run answered 24/3, 2013 at 18:45 Comment(0)
T
0

The MSDN description for NoStringInterning says

"Marks an assembly as not requiring string-literal interning."

Saying that an assembly does not require interning is not the same as saying that the feature should be turned off. AFAIK there's no way to do that (except for NGEN).

Twotone answered 24/3, 2013 at 17:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.