Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Better lazy initialization for Encoding static properties#6890

Merged
jkotas merged 2 commits into
dotnet:masterfrom
jamesqo:encoding-lazyinit
Aug 24, 2016
Merged

Better lazy initialization for Encoding static properties#6890
jkotas merged 2 commits into
dotnet:masterfrom
jamesqo:encoding-lazyinit

Conversation

@jamesqo
Copy link
Copy Markdown

@jamesqo jamesqo commented Aug 24, 2016

Previously the Encoding properties were not being inlined and made use of volatile fields, which are particularly costly on ARM (I think). This changes them to use nested static classes instead, which are a better way to perform lazy initialization (#1193) since we bypass checks if the cctor has already been run.

Partially addresses #6759

Unfortunately this only made a small impact (< 10%, maybe 6-8%) for cases like

Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(""));

since Encoding is basically a landmine of virtual method calls. However the difference is still there, and the diff is mainly red.

cc: @jkotas @omariom

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is wasteful to create new holder types for these - even trivial type costs 100's bytes at runtime. It would better to make these readonly variables in the respective encoding types:

public class ASCIIEncoding
{
    internal readonly ASCIIEncoding Instance = new ASCIIEncoding();
...

Similar pattern is used in number of places in coreclr and corefx.

Copy link
Copy Markdown
Author

@jamesqo jamesqo Aug 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkotas I saw your suggestion in the other issue, however I did not follow it for reasons of code cleanliness (people might wonder why there is a static field being used nowhere in the file).

Perhaps what I'll do is make all the Encoding subclasses partial, and then have a file like Encoding.StaticProperties.cs (probably with a better name) and keep all of the static property-initialization logic in there. That way, the comment will not have to be repeated per-Encoding, and there won't be a need for all of these new classes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see a problem with internal static field that is not used anywhere else in the file. It is pretty common with the existing uses of this pattern.

One example out of many:

internal static readonly TraceLoggingDataCollector Instance = new TraceLoggingDataCollector();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkotas Yeah, but the example you pointed out is a singleton. UTF8Encoding on the other hand has a public constructor, so naming it Instance or s_instance will be confusing since you can create multiple instances of it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be called DefaultInstance

@jamesqo
Copy link
Copy Markdown
Author

jamesqo commented Aug 24, 2016

@jkotas I have made the changes you suggested; thanks for reviewing. (I used Interlocked.CompareExchange pattern to initialize the Default property.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generates warnings:

warning CS0108: 'ASCIIEncoding.Default' hides inherited member 'Encoding.Default'. Use the new keyword if hiding was intended.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readonly field would have same effect, with more compact IL...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@jamesqo jamesqo force-pushed the encoding-lazyinit branch from 01ec3de to 66d9c20 Compare August 24, 2016 13:57
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not right

@jamesqo
Copy link
Copy Markdown
Author

jamesqo commented Aug 24, 2016

Test Windows_NT x64 Release Priority 1 Build and Test
Test Windows_NT x86 ryujit Checked Build and Test
Test Linux ARM Emulator Cross Debug Build

@jkotas jkotas merged commit df50db7 into dotnet:master Aug 24, 2016
@jkotas
Copy link
Copy Markdown
Member

jkotas commented Aug 24, 2016

Thanks!

@jamesqo jamesqo deleted the encoding-lazyinit branch August 25, 2016 00:08
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…eclr#6890)

Better lazy initialization for Encoding static properties

Commit migrated from dotnet/coreclr@df50db7
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants